Adam Sznajder
Adam Sznajder

Reputation: 9206

Why changing the prototype does not affect previously created objects?

I have the following code:

var A = function() {};
var a = new A();
var b = new A();
A.prototype.member1 = 10;

A.prototype = {}
var c = new A();
console.log(a.member1);
console.log(a.constructor === b.constructor);
console.log(a.constructor === c.constructor);
console.log('---------');
console.log(c.member1);

It's output is:

10
true
false
---------
undefined
undefined

The prototype of a and b has not changed and c had a new one. Am i right that this was caused by the fact that a.constructor is not equal to c.constructor and each of them had own prototype? Are there any other circs when constructors of two objects might not be equal?

Extra question: why there were printed two undefined strings? (Chromium)

Upvotes: 5

Views: 338

Answers (3)

Imp
Imp

Reputation: 8609

At the time you're calling

var a = new A();

basically this assignment is done:

a.__proto__ = A.prototype;

Then you reassign the A.prototype to a new object, so c gets {} as its prototype.

A.prototype = {};
var c = new A();

However, this doesn't destroy the old A.prototype object - a.__proto__ is still pointing to it.

Am i right that this was caused by the fact that a.constructor is not equal to c.constructor and each of them had own prototype?

.constructor is basically just a convenience property. It has no effect on how instances behave.

Extra question: why there were printed two undefined strings?

Not in my console, they don't! (Opera 12)

Upvotes: 5

David Nguyen
David Nguyen

Reputation: 331

The answer lies in this line of your code:

A.prototype = {}

When you get to this line of code, you are actually creating a BRAND NEW OBJECT in memory that is {}. Creating any new objects using A as your constructor will point to this BRAND NEW OBJECT as the prototype.

However, the OLD PROTOTYPE still exists in memory. It's just that A.prototype no longer points to it. Any objects you create using A as the constructor before you redefine A's prototype reference are still pointing to this OLD PROTOTYPE as it's prototype.

Upvotes: 2

user578895
user578895

Reputation:

When you create an object, the prototype of the constructor is assigned to the __proto__ property of the new object. You're then changing the prototype, but the two a and b objects are already pointing at the original reference:

var a = new A();
// a.__proto__ == A.prototype == {} (soon == {member1:10})
var b = new A();
// b.__proto__ == A.prototype == {} (soon == {member1:10})

A.prototype = {} // this changes A.prototype, but not a.__proto__ or b.__proto__
var c = new A(); // c.__proto__ = {}

your first undefined is from c.member1. The 2nd one is chrome saying your entire statement had no return value

Upvotes: 2

Related Questions