Constructors



If you want to create some objects:
var p1 = {name : 'Justin', age : 35};
var p2 = {name : 'Momor', age : 32};
var p3 = {name : 'Hamimi', age : 2};
These objects have the same properties but different values. You can define a function.
function Person(name, age) {
    this.name = name;
    this.age = age;
}

Calling it as follows will have the same effect:
var p1 = new Person('Justin', 35);
var p2 = new Person('Momor', 32);
var p3 = new Person('Hamimi', 2);


Once you have a function like Person, you can use the new operator to construct an object. Functions such as Person are so-called object constructors. Developers from class-based languages might also say it's like a class. This is just an analogy but it's different from a class.

Actually, when you new a function, you do things such as follows: (There are still more details and I will talk about it afterward.)
js> function Person(name, age) {
  >     this.name = name;
  >     this.age = age;
  >     this.toString = function() {
  >         return '[' + this.name + ', ' + this.age + ']';
  >     };
  > }
js> var p = {};
js> Person.call(p, 'Justin', 35);
js> p

[Justin, 35]
js>

This also explains why new followed by the Person function will return an object with name and age. In the function, this and p has the same reference so if you add properties to this, it equals adding properties to p.

While a function is used as a constructor, basically, you don't need to return anything. If you return something from a constructor, what you get is the returned value but not this reference. For example:
js> function Person(name, age)  {
  >     return [];
  > }
js> var o = new Person();
js> o instanceof Person;
false
js> o instanceof Array;
true
js>


If there's a constructor after new, it has the effect like the following:
js> function Person(name, age) {
  >     this.name = name;
  >     this.age = age;
  >     this.toString = function() {
  >         return '[' + this.name + ', ' + this.age + ']';
  >     };
  >     return this;
  > }
js> var p = {};
js> p = Person.call(p, 'Justin', 35);
[Justin, 35]
js>


Every object created by new has a constructor property which refers to the constructor function of the object. For example:
js> function Person() {}
js> var p = new Person();
js> p.constructor == Person
true
js>


The constructor property can be a reference for determining what type of an object is. But be careful, the constructor property is updatable.

In the constructor, properties are created on the object referred by this, the default returned object of a constructor, so you can access them through the dot operator. For example: 
js> function Person(name, age) {
  >     this.name = name;
  >     this.age = age;
  > }
js> var p = new Person('Justin', 35);
js> p.name;
Justin
js> p.age;
35
js>

People familiar with other object-oriented languages, such as Java, might think name and age unsafe because they are not private properties. On the contrary, they are like public properties of a class-based object. JavaScript itself does not support private accessibility of some object-oriented languages. If you want to simulate a private property, as follows:
js> function Person(name, age) {
  >     this.getName = function() {
  >         return name;
  >     };
  >     this.age = age;
  > }
js> var p = new Person('Justin', 35);
js> print(p.name);
undefined
js> print(p.getName());
Justin
js> print(p.age);
35
js>


In the above example, you cannot update name directly but can retrieve it through getName(). That's because the function referred by getName, a property of this, is a closure. It closes the parameter name. A parameter is also a local variable so you cannot access it directly. You have to use the getName property of the returned object, namely this. This is a way for JavaScript to define a so-called private variable.

What a closure closes are variables so you can protect variables while updating them, such as follows:
js> function Account() {
  >     var balance = 0;
  >     this.getBalance = function() {
  >         return balance;
  >     };
  >     this.setBalance = function(money) {
  >         if(money < 0) {
  >             throw new Error('can\'t set negative balance.');
  >         }
  >         balance = money;
  >     };
  > }
js> var acct = new Account();
js> acct.getBalance();
0
js> acct.setBalance(1000);
js> acct.getBalance();
1000
js> acct.setBalance(-1000);

js: "<stdin>", line 113: exception from uncaught JavaScript throw: Error: can't
set negative balance.
        at <stdin>:113
        at <stdin>:111

js>

js> print(p.age);
35
js>