ref – http://book.mixu.net/node/ch6.html
The new constructor call (e.g. new Foo()):
creates a new object,
sets the prototype of that object to Foo.prototype and
passes that as this to the constructor.
The prototype chain lookup mechanism is the essence of prototypal inheritance.
1 2 3 4 5 6 7 8 9 10 11 12 |
// Constructor function Foo(bar) { // always initialize all instance properties this.bar = bar; this.baz = 'baz'; // default value } // class methods Foo.prototype.fooBar = function() { }; // export the class module.exports = Foo; |
Instantiate the class:
1 2 |
// constructor call var object = new Foo('Hello'); |
Adding private variables
1 2 3 4 5 6 7 8 9 10 11 12 |
// Private variable var total = 0; // Constructor function Foo() { // access private shared variable total++; }; // Expose a getter (could also expose a setter to make it a public variable) Foo.prototype.getTotalObjects = function(){ return total; }; |
Avoid assigning variables to prototypes
If you want to define a default value for a property of an instance, define it in the constructor function.
Prototypes should not have properties that are not functions, because prototype properties that are not primitives (such as arrays and objects) will not behave as one would expect, since they will use the instance that is looked up from the prototype. Example for Dimitry Sosnikov’s site:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
var Foo = function (name) { this.name = name; }; Foo.prototype.data = [1, 2, 3]; // setting a non-primitive property Foo.prototype.showData = function () { console.log(this.name, this.data); }; var foo1 = new Foo("foo1"); var foo2 = new Foo("foo2"); // both instances use the same default value of data foo1.showData(); // "foo1", [1, 2, 3] foo2.showData(); // "foo2", [1, 2, 3] // however, if we change the data from one instance foo1.data.push(4); // it mirrors on the second instance foo1.showData(); // "foo1", [1, 2, 3, 4] foo2.showData(); // "foo2", [1, 2, 3, 4] |
Hence prototypes should only define methods, not data.
1 2 3 4 5 6 7 8 9 |
function Foo(name) { this.name = name; this.data = [1, 2, 3]; // setting a non-primitive property }; Foo.prototype.showData = function () { console.log(this.name, this.data); }; var foo1 = new Foo("foo1"); var foo2 = new Foo("foo2"); foo1.data.push(4); foo1.showData(); // "foo1", [1, 2, 3, 4] |