1
function User() {
  this.name = "name";
}

User.prototype.age = 10;

const user1 = new User(); // user1 -> { name: "name" }

console.log(user1.age) // prints 10
console.log(user1.__proto__ === user.prototype) // prints true

// if i change the age value on prototype, then user1.age will return the new value
User.prototype.age = 20;
console.log(user1.age) // prints 20

The above code works as expected, because when i call "User" function with keyword new it will return an object that only has name property and that object will be linked to User.prototype.

But What i don't get is when I've assigned the prototype with an object, there's no link anymore.

User.prototype = {age: 30};

console.log(user1.age) // prints 20! , Why?, shouldn't it print 30?
console.log(user1.__proto__ === User.prototype) // prints false

P.S: even if the link is lost because the reference of User.porotype has been changed, but why user1.age is still returning 20 not undefined

Edit: As the answers have mentioned, this has nothing to do with prototype, I've got confused because i was thinking that the object reference is like a pointer which is not. Which was already answered here Javascript pointer/reference craziness. Can someone explain this?

  • Well, you’ve replaced the object. The class’ `prototype` and the instance’s `__proto__` are now two different objects. – deceze Oct 29 '20 at 19:00

2 Answers2

1

When you reassign the .prototype property, old instances which used to have their internal prototype point to the old prototype do not get changed. See the docs on setPrototypeOf:

Warning: Changing the [[Prototype]] of an object is, by the nature of how modern JavaScript engines optimize property accesses, currently a very slow operation in every browser and JavaScript engine. In addition, the effects of altering inheritance are subtle and far-flung, and are not limited to simply the time spent in the Object.setPrototypeOf(...) statement, but may extend to any code that has access to any object whose [[Prototype]] has been altered.

If old instances had their prototypes automatically updated, it would be a very expensive operation, and could cause odd breakages. Assigning a new object to the .prototype will only affect new instances.

If you want to update the prototypes of existing instances, you'd have to do it manually (for informational purposes only - it's a very strange thing to want to do in the first place)

function User() {
}
const user1 = new User();
User.prototype = { age: 30 };
Object.setPrototypeOf(user1, User.prototype);

console.log(user1.age)
console.log(user1.__proto__ === User.prototype)
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
1

when you declare const user1 = new User();, behind the scene you will get user1.__proto__ = User.prototype.

Reassigning User.prototype later to another object will not affect user1.__proto__, the value will remain the same as before, it will keep a reference to the original prototype object.

In fact, it has nothing to do with the prototype thing, it's just related to object affectation like in the following example :

let obj1 = {a: 2};
const obj2 = obj1;
obj1 = {b: 2}
   
console.log(obj2); // print {a: 2}
Olivier Boissé
  • 15,834
  • 6
  • 38
  • 56