Home > other >  Inheritance and the prototype chain: reassigning the Constructor.prototype
Inheritance and the prototype chain: reassigning the Constructor.prototype

Time:11-13

I'm trying to improve my knowledge on object, constructors, prototype and all that stuff related to objects in JS. I was reading a post on MDN about inheritance and the prototype chain and I came across this explanation about why you should not reassign the Constructor.prototype after you created the instances. I cannot understand what those two reasons mean:

function Box(value) {
  this.value = value;
}
Box.prototype.getValue = function () {
  return this.value;
};
const box = new Box(1);

// Mutate Box.prototype after an instance has already been created
Box.prototype.getValue = function () {
  return this.value   1;
};
box.getValue(); // 2

Their explanation:

A corollary is, re-assigning Constructor.prototype (Constructor.prototype = ...) is a bad idea for two reasons:

  • The [[Prototype]] of instances created before the reassignment is now referencing a different object from the [[Prototype]] of instances created after the reassignment — mutating one's [[Prototype]] no longer mutates the other.

  • Unless you manually re-set the constructor property, the constructor function can no longer be traced from instance.constructor, which may break user expectation. Some built-in operations will read the constructor property as well, and if it is not set, they may not work as expected.

CodePudding user response:

The article is referring to this behavior:

function Box(value) {
  this.value = value;
}
Box.prototype.getValue = function () {
  return this.value;
};
const box1 = new Box(1);

// Mutate Box.prototype after an instance has already been created
Box.prototype = {
  getValue() {
    return this.value   42;
  }
}

const box2 = new Box(1);

console.log(box1.getValue()); // 2
console.log(box2.getValue()); // 43

If you assign a new value to Box.prototype then only newly created instances will have this new value as their prototype. Mutating the existing prototype object as in your example is not a problem (but still not common).

Unless you manually re-set the constructor property, the constructor function can no longer be traced from instance.constructor ...

Compare the following

function Box(value) {
  this.value = value;
}
const box1 = new Box(1);
console.log('box1.constructor === Box:', box1.constructor === Box);

Box.prototype = {
  getValue() {
    return this.value   42;
  }
}

const box2 = new Box(1);
console.log('box2.constructor === Box:', box2.constructor === Box);

Box.prototype = {
  constructor: Box,
  getValue() {
    return this.value   42;
  }
}

const box3 = new Box(1);
console.log('box3.constructor === Box:', box3.constructor === Box);

Unless constructor is explicitly set after assigning to Box.prototype, box.constructor does not refer to Box.


This might useful:

  • Related