3

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?
1
  • Typically you define a property in the constructor instead of the prototype to give each instance a property that returns true for object.hasOwnProperty(propname). Commented Aug 8, 2011 at 23:55

1 Answer 1

12

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;
Sign up to request clarification or add additional context in comments.

3 Comments

So, it sounds like you're saying that if you want something to be the same for every instance, you set it on the prototype. If you want something to be allowed to be different on every instance, you define it on the instance. And, lo and behold, you want methods to be the same for every instance (thus you assign them to the prototype) and you want data to be allowed to be different for every instance so you assign them in the instance (typically in the constructor)
Thank you for this explanation, I was hopelessly trying to figure out why my prototype arrays were sharing values while my prototype fields were not. I'm now creating new arrays in the constructor functions for my objects.
@Brian: Your welcome! Exactly, you have to initialize the arrays in the constructor then... I should add this to answer, thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.