Prototypal Inheritance in JavaScript

Posted: September 5, 2010 in JavaScript
Tags: , ,

There is a great article written by Douglas Crockford. I recommend everybody to read this article. By using Prototypal inheritance technique, we can create the instance of an object. Suppose, we have one object User, we want to create the instance of the user object and use it in different-2 places.  In order to create the instance of an object, we can set the prototype property of an Constructor Function equal to the object and then we can instantiate that constructor function to create the instance of that object. Below is the create method that will help us to do so. This method is taken from Doug’s article.

//creating a method that will pops up
//the new objects inherited with the old object.
if ( Object.create !== "function" ) {
 Object.create = function (oldObj) {
 function F ( ) {} ;
 F.prototype = oldObj;
 return new F ( );
 }
}

Now let’s say we have one object User that has one property say name that is an array. It has getter setter methods to set and get the name value.

//User is a simple object contains 3 methods and one property
User = {
 name : [],
 addName:function(n)  {
 this.name.push(n);
 },
 getName : function  (  )  {
 alert(this.name);
 }
}

Now, by using create method,  we can create instances of the User object.


//creating one instance of User
var obj1 = Object.create(User);
obj1.addName("Rupesh");
obj1.getName( );

//creating another instance of the User
var obj2 = Object.create(User);
obj2.addName("Ritesh");
obj2.getName( );

We saw that how easily we can create the instances of an object and can use its properties and methods using Prototypal inheritance.

I like Prototypal inheritance because it has many advantages one of them is it saves memory. Because, when we create new object by putting old object in its prototype property then we don’t refer to the concrete old object rather we refer to the property of an object which has a link or which refer to or which points to the concrete old object. It also help us to create the loosely coupled architecture.

However, in above User object there is one problem!!

The problem is when you call obj1.getName( ) it will alert Rupesh. When you call obj2.getName( ) it will alert Rupesh, Ritesh. This is a problem!! This was never expected. We thought that we are creating two different new objects obj1 and obj2. Which will have their own name properties and will store different values. But it is not the case!!!

Let’s analyze the process !

When we write the code obj1.addName(“Rupesh”); The obj1, new object will look for the name property in obj1 object. It will not find the name property in the obj1  object. So, it will go to the prototype object which is a User object and there it will search for the name property and finally it updates the name property of the prototype object which is nothing but the User Object. Therefore, the next time when obj2.addName(“Ritesh”) is called,  it again looks for name property in this (obj2) and it again fails to find the name property in obj2 object. Therefore, it searches in obj2’s prototype object for name property. There exists User object that has name property and obj1 has already entered “Rupesh” in this property so obj2 again enters “Ritesh” in the same name property and hence when we do obj2.getName( ) then it says “Rupesh,Ritesh”.

Whatever data is entered by the obj1 in name property. It is inserted in the prototype objects name property that is also shared with obj2. That means, they are sharing the same name property. It’s like a static property that is being used by the multiple instances of the User object. But, that was not intended. We wanted a new fresh object in each instance.

In order to achieve that, we can introduce one method to User object say init. In this method we will initialized the name property with a new array and assign it to the instance object “this”.

User = {
    init:function ( ) {
       // we are initializing its name property in new instance or new object.
        this.name = [];
    },
    name :[],
    addName:function(n) {
        this.name.push(n);
    },
    getName : function ( ) {
        return this.name;
    }
}

Now if we write below code to set and get the name property then each instance will have different or their own values.

//creating one instance of User
var obj1 = Object.create(User);
//calling its init method
obj1.init( );
//here we are adding the same name property
//to the new instance of the User object.
obj1.addName("Rupesh");
obj1.getName( );

//creating another instance of the User
var obj2 = Object.create(User);
obj2.init( );
obj2.addName("Ritesh");
obj2.getName( );

Now the obj1.getName ( ) will return Rupesh and obj2.getName will return Ritesh. Because, now obj1 and obj2 will have common shared methods but they will have their own distinct name properties. I think, I was able to explain the prototypal inheritance clearly. If you have any suggestions then plz put your comments, I want to learn more from you.

Comments
  1. Satish says:

    This is good. Hope to see more such things from you.

  2. […] your plugin’s methods in the prototype of jquery object. $.fn is the alias for the prototype of the jquery object. In our above example, […]

Leave a comment