From here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures
Performance considerations
function MyObject(name, message) {
this.name = name.toString();
this.message = message.toString();
}
MyObject.prototype = {
getName: function() {
return this.name;
},
getMessage: function() {
return this.message;
}
};
However, redefining the prototype is not recommended. The following example instead appends to the existing prototype:
function MyObject(name, message) {
this.name = name.toString();
this.message = message.toString();
}
MyObject.prototype.getName = function() {
return this.name;
};
MyObject.prototype.getMessage = function() {
return this.message;
};
Above quotes and codes are from the given link.
I want to understand how does the first code suggest that we are redefining the prototype and how does the second code suggest that we are appending the prototype?
What represents redefining and what represents appending in the above pieces of code?
When you redefine the prototype
object you are creating a whole new object, instead of preserving the existing prototype with its properties, this is undesirable.
If we redefine the prototype object, it will break the inheritance hierarchy. Particularly instanceof
and Object.prototype.isPrototypeOf
won't work as expected.
Let's take an example and show a simple inheritance hierarchy with ChildClassOne
and ChildClassTwo
inheriting from ParentClass
.
In the first case the inheritance is broken as the prototype
is overriden with a completely new object which erases every information which was present already, instead of appending to the prototype received from the Object.create
call.
In the second case it works as expected as the prototype is not replaced:
function ParentClass(param) {
this.param = param;
}
ParentClass.prototype.getParam = function() {
return this.param;
}
function ChildClassOne(param, name, message) {
ParentClass.call(param);
this.name = name.toString();
this.message = message.toString();
}
//Inheriting through prototype
ChildClassOne.prototype = Object.create(ParentClass.prototype);
ChildClassOne.constructor = ChildClassOne;
//Prototype completely overriden, destroying the hierarchy
ChildClassOne.prototype = {
getName: function() {
return this.name;
},
getMessage: function() {
return this.message;
}
};
//the instanceof and isPrototypeOf is broken
const child1 = new ChildClassOne("bazz", "foo", "bar");
console.log(child1 instanceof ParentClass);
console.log(ParentClass.prototype.isPrototypeOf(child1));
console.log(ChildClassOne.prototype instanceof ParentClass)
function ChildClassTwo(param, name, message) {
ParentClass.call(param);
this.name = name.toString();
this.message = message.toString();
}
//Inheriting through prototype
ChildClassTwo.prototype = Object.create(ParentClass.prototype);
ChildClassTwo.constructor = ChildClassTwo;
//Preserving the heirarchy information, by appending to existing prototype
ChildClassTwo.prototype.getName = function() {
return this.name;
};
ChildClassTwo.prototype.getMessage = function() {
return this.message;
}
//Works as expected
const child2 = new ChildClassTwo("bazz", "foo", "bar");
console.log(child2 instanceof ParentClass);
console.log(ParentClass.prototype.isPrototypeOf(child2));
console.log(ChildClassTwo.prototype instanceof ParentClass)