JavaScript Inheritance Done Right

One of the worst (and possibly also one of the best) things about JavaScript is that it offers you many ways to do anything. Some tricks are simple and neat while others can be complex and confusing.

If you have done some research, you will likely have come across many ways of implementing inheritance in JavaScript. I have personally used a lot of variations over time in various projects but it’s not until recently that I have settled on a particular technique.

I have chosen this particular technique because I feel that it most closely resembles how most OO programming languages implement inheritance. To get it to work properly, you should use the prototype-based method of class definition. Here is an example of the technique in action:

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

BaseClass.prototype.foo = function (arg) {
    return ‘This is the foo method with argument: ‘ + arg;
};

function SubClass(name) {
    // Call the base class’ constructor.
    BaseClass.call(this, name);
}

// SubClass’ prototype is based on BaseClass’ prototype
SubClass.prototype = Object.create(BaseClass.prototype);

SubClass.prototype.sub = function () {
    return ‘This is the sub method.’
}

SubClass.prototype.foo = function (arg) {
    // Call the base class foo method on the current instance
    return BaseClass.prototype.foo.call(this, arg) + ‘ SUB';
}

Ok, so what stands out the most in this code is this line:

SubClass.prototype = Object.create(BaseClass.prototype);

When you define a function in JavaScript, initially, its prototype will be an empty object. What we’re doing here is setting the SubClass’ prototype to be a new instance which shares the BaseClass’ prototype. Effectively, this allows us to freely modify the SubClass’ extended prototype without messing with the BaseClass’ prototype – The advantage of this technique over simply cloning the prototype is that changes in the BaseClass prototype will still be reflected in the SubClass (but not the other way around). The best way to think about the Object.create() method is that it instantiates a class based on a prototype without actually going through its constructor. The Object.create() function may not be supported by older browsers, but thankfully there is a simple polyfill which you can get from this page:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create

The second weird thing about the code above is this line:

BaseClass.call(this, name);

Now if you don’t know what call or apply do, you should check this:
http://stackoverflow.com/questions/1986896/what-is-the-difference-between-call-and-apply

OO languages usually offer a way to explicitly call a super class’ constructor or method, JavaScript is no exception. With JavaScript, you just call the constructor/method using either call() or apply() and pass a reference to the current instance as the first argument. This is a neat feature of JavaScript which allows you to effectively borrow methods from any other class to use on the current instance.

If you’re used to languages like Java, C# and Python, you might find the class definitions above unusual – In these languages you have an explicit ‘class’ keyword and you define the methods INSIDE the class block. If however, you have written C++ before, this might seem a little less confusing because C++ allows you to define methods of a class outside of the class definition block. While JavaScript does let you define methods inside the constructor’s function block, this makes inheritance more difficult to achieve and I would strongly recommend that you follow the technique above (I swear you won’t regret it).

About these ads

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