1

So I'm currently working with JavaScript inheritance using multiple classes, so there are multiple levels to the inheritance.

I've looked around for a lot of methods and the easiest and best method I've found is using .call(). So for example:

function DerivedClass ( para1, para2)
{
    BaseClass.call(this, para1, para2);
    //Insert more code here
}

DerivedClass.prototype = Object.create(BaseClass.prototype);
DerivedClass.prototype.constructor = DerivedClass;

Now, this works for me and that's fine, I'm happy with that. But I'm the sort of programmer that needs to know why or how something works before I can continue.

However, the above code works fine, and exactly the same (at least for what I'm doing with it), if I only use .call() and don't put the .prototype and .constructor stuff at the end.

Could someone explain to me why the two bottom lines are necessary with this method if the inheritance still works fine without them?

Thanks.

Joeb Rogers
  • 348
  • 1
  • 2
  • 14
  • 3
    I'd assume "Because you weren't using the prototype for anything in the first place", but it is hard to say without seeing BaseClass. – Quentin Apr 12 '16 at 09:35
  • Try to put some methods on the child prototype and see if anything changes. Or try to call a prototype method of the parent. Also, `new DerivedClass instanceof BaseClass` (and more)… No, it does not work fine without them. – Bergi Apr 12 '16 at 09:35

2 Answers2

1
DerivedClass.prototype = Object.create(BaseClass.prototype);

This is required to implement the whole inheritance. DerivedClass inherits BaseClass because DerivedClass prototype is BaseClass.prototype plus new, and exlusive DerivedClass members.

This way, DerivedClass instances will be able to access BaseClass members too, and so on (if you continue the prototype chain with a third object).

In the other hand, if you miss the part of chaining prototypes, you're not implementing inheritance. The code...

BaseClass.call(this, para1, para2);

...is just equivalent of class-based OOP languages call to the base constructor. ECMA-Script 6/2015 and above has already it:

class Derived extends Base
{
      constructor(a, b) 
      {
          // This is the same as Base.call(a, b);
          super(a, b);
      }
}

In summary, you would add properties added inside the BaseClass constructor, but this isn't inheritance in terms of how JavaScript works. See this other Q&A to get more details: Javascript: Understanding Prototype chain

For the other code (the constructor setting thing), you should check this other Q&A: Why is it necessary to set the prototype constructor?

Community
  • 1
  • 1
Matías Fidemraizer
  • 63,804
  • 18
  • 124
  • 206
1

I assume that you have looked around a lot of ways to do inheritance in JavaScript but missed on the core concept behind all of them.

One way to achieve inheritance in JavaScript is by prototype chaining. By this process the child class points to the parent class by a __ proto__ (underscore underscore proto underscore underscore) link.

To be short there are two properties to look for while doing inheritance in JavaScript

  1. Prototype -> property of a function
  2. __ proto__ -> property of an object

the proto link is used by JavaScript to look for properties present in the parent if not found in the child.

Lets take an example:

var base{
    prop1 : 4,
    prop2 : 100
}

Suppose base is the object which other child classes want to inherit

to inherit this object the child class needs to point its proto link to this object

function Child1(){
  //child1 function body
} 

Child1.prototype = base;

By doing this much objects created from the Child1 function will also have properties of base object, but the constructor of those objects will be shown as Object and not Child1.

To fix this the constructor property also needs to be updated

Child1.prototype.constructor = Child1

What you have done by the .call function is just call the parent function passing the 'this' or context of the current child class into another function not inherited it yet.

If you omit out the last two lines then the object created by DerivedClass will not contain properties of BaseClass

Himanshu Tanwar
  • 906
  • 6
  • 18