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:

code snippet output

But I have the impression that I am missing a very important point. My question is, what happens with the second approach?

+3


source to share


5 answers


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);
      

Run code


+2


source


When you add a new property to Sub.prototype

, you don't want it to affect Base.prototype

, do you? This will be very difficult.: -)



Using an approach new Base()

means that any changes you make in Sub.prototype

will not "seep" before Base.prototype

.

+4


source


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

+4


source


If you are using Sub.prototype = Base.prototype;

, you cannot add any methods to Sub.prototype without having them in Base.prototype, because they are the same object.
Except for the constructor, Sub and Base will be exactly the same.

+3


source


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

      

Sample script

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.

0


source







All Articles