Sub.prototype = new Base () vs Sub.prototype = Base.prototype
There are many JavaScript prototypes and inheritance on the web. Most of them use code like this:
function Base() {}
function Sub() {}
with inheritance implemented like this:
Sub.prototype = new Base();
But I'm wondering what is wrong with inheritance implemented this way:
Sub.prototype = Base.prototype;
The second seems to work just as well. The only two differences I noticed (that IMO is an advantage of the second approach):
- there is another dummy instance
Base
which is obviously better as the instance is never used anyway - checking the instances shows that the first approach creates two nested ones
__proto__
and the second only one, which is what the instance cleaner does.
The latter is illustrated by the following code snippet:
function Base(){}
Base.prototype.bogus = function(){};
function SubNew(){}
function SubProto(){}
SubNew.prototype = new Base();
SubProto.prototype = Base.prototype;
var sn = new SubNew();
var sp = new SubProto();
console.log(sn);
console.log(sp);
gives:
But I have the impression that I am missing a very important point. My question is, what happens with the second approach?
source to share
When you use the same prototype, you don't inherit anything, you just create a different type that is a copy of the first.
If you put anything in an object of the base type, it won't inherit if you just get a prototype:
function Base(){
this.answer = 42;
}
function SubNew(){}
function SubProto(){}
SubNew.prototype = new Base();
SubProto.prototype = Base.prototype;
var sn = new SubNew();
var sp = new SubProto();
// show result in StackOverflow snippet
document.writeln(sn.answer);
document.writeln(sp.answer);
source to share
I would install it this way
function Base() {}
function Sub() {
// call parent constructor; optional
Base.call(this);
}
Sub.prototype = Object.create(Base.prototype, {constructor: {value: Sub}});
This is very similar to how util.inherits works in node.js
source to share
Basically, if you assign a property prototype
, you create a different constructor that will create objects that project the same object, not inheritance, you will see this in this example:
function Base() { }
function SubType() { }
function YourCase() { }
SubType.prototype = Object.create(Base.prototype);
YourCase.prototype = Base.prototype;
Base.prototype.foo = 1;
SubType.prototype.foo = 2;
YourCase.prototype.foo = 3;
console.log(new Base().foo); // 3 WAT?
console.log(new SubType().foo); // 2
console.log(new YourCase().foo); // 3
If we use the same object in a subtype YourCase.prototype = Base.prototype
when editing YourCase.prototype
, you are editing as well Base.prototype
, because it is the same object.
For this you need to use Object.create(Base.prototype)
or new Base()
to extend the prototype.
source to share