I have read through some tutorials about javascript prototypal inheritance patterns but I am not sure which is the best practice out of the following two. I noted that many people do this inheritance pattern:
var A = function (){}
A.prototype = {}
var B = function () {
A.apply(this, arguments); // Calling the constructor of A
}
B.prototype = new A(); // Inherit from A through an instance
Alternative, there are some sources that do the following pattern instead:
var A = function (){}
A.prototype = {}
var B = function () {
A.apply(this, arguments); // Calling the constructor of A
}
for (var prop in A.prototype) {
B.prototype[prop] = A.prototype[prop]; // Inherit from A by copying every property/methods from A
}
Although both patterns work, I rarely see people use the latter inheritance pattern (ie. copying each property/methods from the parent’s prototype) – why? Is there something wrong with copying properties/methods directly from parent to child? Also, are these two patterns intrinsically different in some ways?
Thank you.
These patterns are very different, and as you may have guessed, the first is better (but not the best possible). Let us compare:
The Most Modern, Best Pattern
This uses the
Object.createfunction to setB.prototypeto a new object, whose internal[[Prototype]]isA.prototype. This is basically exactly what you want: it will makeBinstances delegate toA.prototypewhen appropriate.The Original Pattern
This was how things used to be done, before ES5’s
Object.createcame about. (Although there were workarounds, even if they were not widely used.) The problem with this approach is that any instance-only data properties also end up onB.prototype, which is not desired. Additionally, any side effects of callingA‘s constructor will happen. Essentially this approach muddles two related, but different concepts: object instantiation, and object construction.The Non-Standard Pattern from Your Post
This pattern has several problems:
A‘s prototype chain, all the way down toObject, directly intoB.prototype. This defeats much of the purpose of prototypal inheritance, wherein you should be delegating up the prototype chain, instead of squashing it into one single level.A.prototypeand its prototype chain, sincefor ... inskips non-enumerable properties.A.prototype(or its prototype chain), simply copying over their value instead of the getter/setter functions.