3

To implement inheritance in Javascript, one generally does the following 2 steps;

Say I have a base class "Animal"

var Animal = function(name){
this.name = name;
}

I now want to derive a sub class "Dog" from the same. So I would say

var Dog = function(name) {
   Animal.call(this,name);
}

So I am calling my parent class constructor from my derived class constructor. The 2nd step is to set the prototype as follows;

Dog.prototype = new Animal();

Now I can access any of the base "Animal" class properties from within my derived class Dog.

So my question is why are these 2 steps necessary ? If we just call the base class constructor using

Animal.call(this,name);

isn't that enough for implementing Inheritance ?

Why do we also need to set the prototype property using Dog.prototype = new Animal(); ?

I wanted to understand what each of the above 2 steps does ?

copenndthagen
  • 49,230
  • 102
  • 290
  • 442
  • 1
    you don't have anything to *inherit* here. – jAndy Mar 07 '13 at 08:03
  • 1
    Because the `Animal` can also inherit using a prototype chain. Simply calling the parent constructor will not keep that inheritance chain. – Sim Mar 07 '13 at 08:03
  • Is it TRUE to say that call() just inherits properties from base class while the 2nd step (setting prototype) inherits methods from base class ? – copenndthagen Mar 07 '13 at 08:41
  • @testndtv `call()` doesn't perform inheritance, it simply adds new members (properties or methods) to `this`, while `new` inherits any members of the parent class prototype. See my answer for details :) –  Mar 07 '13 at 09:01

6 Answers6

2
var Animal = function(name){
    this.name = name;
}
Animal.prototype.sleep = function() {
    console.log("Sleeping")
}

... 
// Without this line:
Dog.prototype = new Animal();

// the following code will fail, since `d` does not contain `sleep`
d = new Dog();
d.sleep();

Animal.call(this,name); simply calls the function Animal, but using the same this as the calling function.

Dog.prototype = new Animal(); sets the prototype of the prototype. However, Dog.prototype = Object.create(Animal.prototype) might be more correct.

Eric
  • 95,302
  • 53
  • 242
  • 374
  • I'm uncertain about that `Dog.prototype = Object.create()`, because `Object.create()` will already set the `.prototype` of the newly created object with the one you pass in. – jAndy Mar 07 '13 at 08:05
  • @jAndy: Isn't that kind of the point? You want `Dog.prototype.__proto__` to be `Animal.prototype`, so that members are inherited, but you don't want `Dog.prototype` to be a full instance of `Animal`. – Eric Mar 07 '13 at 08:09
  • Beware, `Object.create()` is [not compatible with IE less than 9](http://kangax.github.com/es5-compat-table/) and some other browsers. –  Mar 07 '13 at 11:32
1

A code sample is worth a thousand words :)

var Animal = function(name) {
    this.name = name;
}
Animal.prototype.run = function () {
    // do something
};
var Dog = function(name) {
   Animal.call(this, name);
}

var dog = new Dog('Puppy');
typeof dog.name; // "string"
typeof dog.run; // "undefined"
dog instanceof Animal; // false
dog instanceof Dog; // true

Dog.prototype = new Animal();

var dog = new Dog('Puppy');
typeof dog.name; // "string"
typeof dog.run; // "function"
dog instanceof Animal; // true
dog instanceof Dog; // true

As you can see, if you don't use Dog.prototype = new Animal();, Animal.prototype members won't be inherited. Moreover, Dog instances won't be considered as instances of Animal.

0

Second step helps you to inherit prototype methods. Imagine that we have more complex class:

function Animal(name) {
  this.name = name;
}

// shared method
Animal.prototype.say = function () {
  alert( this.name );
};

function Dog() {
  Animal.apply(this, arguments);
}

Dog.prototype = new Animal();


var dog = new Dog('Cooper');
// method has been inherited
dog.say(); // alerts 'Cooper'

You can try it here

ValeriiVasin
  • 8,628
  • 11
  • 58
  • 78
0

There are no classes, nor subclasses, in javascript.

call and apply execute a function in the context of a different 'this'. What you have in your sample code is unneeded.

//Create your constructor function:
var Animal = function(){}

Animal.prototype = {
    sleep: function(){
         console.log('zzz');   
    },
    bark: function(name){
         console.log(name +' barks!');   
    }
}

var dog = new Animal();

dog.sleep();
dog.bark('asdasd');
Geuis
  • 41,122
  • 56
  • 157
  • 219
  • `var cat = new Animal(); cat.bark('a cat');`. I think the OP knows that they want inheritance here. – Eric Mar 07 '13 at 08:10
0

Here we define the constructor function for Animal

var Animal = function(name){
   this.name = name;
}

Then define the constructor function for Dog and from inside it we invoke the constructor function of Animal. Just like we do super() in class based object oriented design.

var Dog = function(name) {
   Animal.call(this,name);
}

Then we build the prototype of Dog by consuming the methods defined in the prototype of Animal. Here it does not clone methods in Animal , but a link is set between Dog and Animal using which it re uses the methods in Animal

Dog.prototype = new Animal();

And continue extending it adding more methods

Dog.prototype.showName = function(){
     // do something
}
Diode
  • 24,570
  • 8
  • 40
  • 51
0

The first thing to understand is that in JavaScript there is no classical inheritance, the mechanism we know from C-languages like Java, C# and so fort. In JavaScript, code reuse can be accomplished by using prototypal-inheritance. The only thing we have is objects, blocks of code who are alive and don't need to be instantiated. For example: when a function is invoked on an object - like a method, the current object is inspected whether the function is known. If not found, the engine calls it prototype (which is an other object) and inspects whether the function name is known and can be invoked. When not found, íts prototype is called and so on. So, setting the prototype of a object one can orchestrate the prototype-chain.

To answer your question: nothing is necessary, its up to you what you want. Code reuse is what you want and inheritance is the way you can achieve this (Stoyan Stefanov - JavaScript Patterns). In JavaScript, more ways are available to reuse code.

Furthermore, this is bound to the current context, not always the current object.

Andries
  • 1,547
  • 10
  • 29
  • So when u say, current object is inspected whether the function is known...if not, it's prototype is called and so on...so can we set the prototype for any type of object...like if I inspect for method myMethod1() on myObject1 and if it is not found, can I make the next search on myObject2...i.e. I somehow set the prototype (or parent object) of myObject1 to myObject2... Can us show with an example... – copenndthagen Mar 07 '13 at 08:35
  • Ha! you got the point! Setting an objects prototype is easy as: myobject.prototype = myobject2 – Andries Mar 07 '13 at 09:01
  • So is that kind of same as setting the '_proto_' linking myobject._proto = myobject2 (But '_proto_' is not accessible in all the browsers except Firefox ) – copenndthagen Mar 07 '13 at 11:54
  • You should forget about '__proto__' :) but it is equivalent to prototype. Check out here how confusing the subject is: (http://stackoverflow.com/questions/650764/how-does-proto-differ-from-constructor-prototype). What I'm saying is that it is not needed to understand prototypal inheritance. – Andries Mar 07 '13 at 13:56