Object Oriented JavaScript – Part 3

by Prasanth Gullapalli

As seen in the earlier article, using Constructor pattern and Prototype chaining on their own have got few problems. We resolved those problems by defining a new pattern which amalgamates both the patterns. If we look at the way we have been creating objects so far, it is very much similar to Java. In fact using new keyword sometimes makes the code more complex which we could have avoided using alternatives like Prototypal Inheritance. So the rest of article deals with how to achieve a better form of inheritance without using any new keyword. Also it addresses the issue of redundant properties(masked by the instance properties) on Prototype we have seen in Combination Inheritance.

The term ‘Prototypal Inheritance’ is actually coined by Douglas Crockford. This pattern avoids the use of constructors from the classical inheritance. Here is the skeleton implementation for this pattern:

function object(o){
	function f(){};
	f.prototype = o;
	return f;
}

This is basically like creating a shallow copy of any given object. Consider the following example:

var person={
	name:'Prasanth',
	friends:{'Madan','Naresh'}
};

var anotherPerson = object(person);
anotherPerson.friends.push('Dawood');

alert(anotherPerson.friends); // Madan, Naresh, Dawood
alert(person.friends); // Madan, Naresh, Dawood

This is the same problem we have encountered earlier when creating objects using Prototype pattern. We are not going to use this pattern as it is, rather we will try to make the Combination Inheritance better by using this prototypal inheritance. Let us consider how we implemented combination inheritance:

function Parent(property1, property2){
    this.sampleArray = ['X'];
    this.property1 = property1;
    this.property2 = property2;
}

Parent.prototype={
    constructor:Parent,
    alertProperty1 = function(){
        return this.property1;
    },
    alertProperty2 = function(){
        return this.property2;
    }
}

function Child(property1, property2, property3){
    // Inherit properties from Parent.
    // Call Parent as function by binding 'this' to it
    <strong>Parent.call(this, property1, property2);</strong>
    this.property3 = property3;
}

<strong>Child.prototype = new Parent();</strong>
Child.prototype.alertProperty3 = function(){
    return this.property3;
}

var childObject = new Child('A', 'B', 'C');

If you closely observe, we are calling the parent reference type constructor twice. Once by calling the constructor and yet another time while defining the prototype. So the instance level properties of prototype object i.e. childObject.prototype.sampleArray, childObject.prototype.property1, childObject.prototype.property2(created at line# 24) are actually masked by the instance level properties of subtype i.e. childObject.sampleArray, childObject.property1, childObject.property2((created at line #20). And as properties got masked there is no straight way to access them. So if we could avoid copying instance level properties of prototype, redundancy will be removed. This we will achieve by using the following function:

// Copies the prototype of superType as prototype of subType
function inheritPrototype(subType, superType){
	var prototype = object(superType.prototype);
	prototype.constructor = subType;
	subType.prototype = prototype;
}

Using this function we can only copy the properties/functions defined on the prototype of parent object and not the parent properties. Now replace the child prototype creation with this new method. Hence the code would like this:

function Parent(property1, property2){
    this.sampleArray = ['X'];
    this.property1 = property1;
    this.property2 = property2;
}

Parent.prototype={
    constructor:Parent,
    alertProperty1 = function(){
        return this.property1;
    },
    alertProperty2 = function(){
        return this.property2;
    }
}

function Child(property1, property2, property3){
    // Inherit properties from Parent.
    // Call Parent as function by binding 'this' to it
    <strong>Parent.call(this, property1, property2);</strong>
    this.property3 = property3;
}

<strong>inheritPrototype(Child, Parent)</strong>
Child.prototype.alertProperty3 = function(){
    return property3;
}

var childObject = new Child('A', 'B', 'C');

Note that at line#24, earlier we were creating instance of Parent using new operator. This has been replaced now with inheritProtype method call. So at line# 24, only the prototype properties of Parent get copied to prototype of Child. And at line# 20, the instance level properties of Parent get copied to child object. This resolves all the problems we have been discussing so far. Also note that here in this pattern we are no more using new operator, the syntax that JavaScript has lent from Java.

Advertisements

One thought on “Object Oriented JavaScript – Part 3

  1. following code is not work well, perhaps.
    “Parent.prototype={
    constructor:Parent;
    this.alertProperty1 = function(){
    return this.property1;
    }
    this.alertProperty2 = function(){
    return this.property2;
    }
    }”

    you mean following code, maybe.
    “Parent.prototype={
    constructor:Parent,
    alertProperty1: function(){
    return this.property1;
    },
    alertProperty2 :function(){
    return this.property2;
    }
    }”

    and there are some invalid markups looks like ‘‘.

    but so useful articles.
    Thank you for your these articles!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s