Tuesday, April 26, 2011

Inheritance in Javascript

Javascript does not provide inheritance as a built-in feature like Java/C++ but it can be easily programmed by using the prototype property of an object.

Every Javascript object has two internal properties 'constructor' and '__proto__'. For this post I will just confine to '__proto__' property as it is more instrumental in understanding the prototypal inheritance provided by Javascript. Also, the constructor property is quite confusing and demands an entire post for itself.

Let us see what happens when we create an object invoking new operator on a function.

var Animal = function() { this.eat = function(){console.log('EATING')} }
Animal.prototype = { sleep : function(){console.log('SLEEPING')} }

animal = new Animal();

The __proto__ property of animal object is set from the prototype property of Animal constructor function. That is why the statement animal.__proto__ == Animal.prototype returns true. When we call animal.sleep function the interpreter checks if the animal object has its own property 'sleep' and if it does not, then it searches for 'sleep' property in animal.__proto__ object.

Similarly when we call animal.toString() method, then it checks for toString property inside animal object and finds nothing there. Then it goes ahead and checks in animal.__proto__ object and finds nothing there. It does not stop there and checks for toString property in animal.__proto__.__proto__ object which points to Object.prototype object. It finally finds the toString property there and then executes it. And, since the Animal object did not override the toString method of Object object we get the raw output "[object Object]".

This form of chaining of prototypes forms the basis of inheritance in Javascript. Let us create a Dog object to see how we can create a inheritance hierarchy :

var Dog = function(){this.bark = function(){console.log('BARKING')}}

Dog is an animal so it needs to inherit from Animal. All we need for this is to set the prototype of the Dog object to point to an Animal object :
 Dog.prototype = new Animal(); 

Above statement sets Dog.prototype.__proto__ to Animal.prototype which is what we wanted. We now instantiate dog objects using the Dog function we created.
dog = new Dog();

We can now call dog.bark() , dog.sleep(), dog.eat() and dog.toString() seamlessly.

No comments: