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
constructorproperty, the constructor function can no longer be traced frominstance.constructor, which may break user expectation. Some built-in operations will read theconstructorproperty 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
constructorproperty, the constructor function can no longer be traced frominstance.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:
