David Battey
David Battey

Reputation: 33

Why are instance methods defined in the prototype but instance fields are defined in the constructor?

When doing inheritance in JavaScript, the pattern that I always see defines instance methods in the prototype, but instance fields in the constructor (see example below). What is the motivation for this? Why not be consistent and define both in the prototype?

function MyClass() {
    this.myField = 0; // why this...
}
MyClass.prototype.myField = 0; // ...instead of this?

Upvotes: 3

Views: 550

Answers (1)

Felix Kling
Felix Kling

Reputation: 816810

Explanation

Because prototype properties are shared between all instances as every instance has a reference to the same prototype object.

This is not an issue with immutable types, you could do:

MyClass.prototype.myField = 0;

var a = new MyClass();
a.myField = 42;

and only a would have this value. This is because the assignment creates the property myField for a. You can test this with calling a.hasOwnProperty('myField') before and after the assignment.

But if you have objects or arrays

MyClass.prototype.myField = [];

and you just append to that array and don't assign a new array (like a.myField = []), then every instance has the new value in that array.


Solution

You have to initialize arrays and objects in the constructor, so that each instance gets its own object or array instance. Some style guidelines propose that you still create the property on the prototype, but initialize it with null. This has no benefit other than adding some conceptual structure (if such a word exists) to your code.

For example:

function MyClass() {
    this.myField = [];
}

/**
 * @type {Array}
 */
MyClass.prototype.myField = null;

Upvotes: 12

Related Questions