Offirmo
Offirmo

Reputation: 19860

What is the correct prototype affectation in javascript inheritance?

I read several articles on js inheritance already (this one, this one, this one, etc.)

In this article from Mozilla, "classic" inheritance is shown as this : (I uniformized examples)

// inherit Base
function Derived() { ... }
Derived.prototype = new Base();            <-------
Derived.prototype.constructor = Derived;   <-------

However in this article I see :

// inherit Base
function Derived() { ... }
Derived.prototype = Object.create(Base.prototype);    <-------
Derived.prototype.constructor = Derived;

Moreover I have also seen this :

Derived.prototype = Base.prototype;

And I also experimented and couldn't find the use of constructor affectation :

Derived.prototype.constructor = Derived; <--- it still work if I skip this line

if I skip this line, new Derived() correctly calls Derived() anyway.

So 1) what is correct :

  1. Derived.prototype = new Base();
  2. Derived.prototype = Object.create(Base.prototype);
  3. Derived.prototype = Base.prototype;
  4. other ?

And 2) is Derived.prototype.constructor = Derived; really needed ? Why ?

Upvotes: 5

Views: 177

Answers (2)

Bergi
Bergi

Reputation: 665040

Derived.prototype = new Base();

This does call the Base constructor just for setting up the prototype chain. While sometimes working and giving equivalent results to Object.create, it is error-prone and should be avoided. Read What is the reason to use the 'new' keyword at Derived.prototype = new Base (and why it should not be used).

Derived.prototype = Object.create(Base.prototype);

This is state of the art - Correct javascript inheritance so to say.

Derived.prototype = Base.prototype;

This is plain wrong. Do not use. It lets Base and Derived instances inherit from the same object - while it (seldom) can be helpful to have multiple constructors for a "class", this is not "subclassing".

Is Derived.prototype.constructor = Derived; really needed? Why?

It can be omitted and your script will work nonetheless, but for convenience you would expect that (new Derived).constructor === Derived. Also have a look at JavaScript inheritance and the constructor property

Upvotes: 3

Tibos
Tibos

Reputation: 27833

What is the correct way to do classical inheritance in JavaScript

In this answer i explained the difference between 1 and 2 showing why 2 is the best way to emulate classical inheritance in JavaScript.

In short, in solution 1 children inherit from an instance of the parent. In solution 2 the class of the children (Derived.prototype) inherits from the class of the parent(Base.prototype). This imposes severe limitations on the parent, because it must be called with 0 arguments.

The 3rd solution is even worse because the prototypes of the Derived and the Base class are the same object, so no method overriding can take place. Even worse, a method defined in Derived.prototype will be available for all Base instances and if a method with the same name had been declared on Base.prototype, it would simply be replaced.

Conclusion: 2 is the true way to do classical inheritance in JavaScript.

Is setting the constructor property needed

Setting the constructor property on the prototype makes it accessible to all instances. That is simply for convenience, the inheriting part works without it.

Upvotes: 1

Related Questions