Simple JavaScript Inheritance Using CoffeeScript Extends

Handwritten by TVD

The Most Attractive Photo On The Internet

I tend to favor object composition over class inheritance. This is especially true when I’m modeling a business process because business is about distinct people coming together to produce a particular result.

Organizations have hierarchy. Yet, that “coming together” is typically more functional than hierarchical. One can say teams are “composed” of distinct functional specialties (Designer, Developer, UX, etc.) and so a modern composite approach to object oriented programming lends more naturally to the way work actually gets done.

Isn’t This Article About JavaScript Inheritance?

Yes.

But, I wanted you to understand class inheritance is only one approach to object oriented programming. Better yet, I want you to see examples of how others use both the object composition and class inheritance techniques.

For example, I find class inheritance particular useful when modeling a distinct real world object. On the flip side, I find object composition works great when modeling Line of Business applications and other games.

Modeling Buttons, Bases and Shiny Things

Take the power panel for example:

JavaScript Power Panel

In particular, let’s focus on two components of the power panel:

1. Glow Starter Light

2. Fuel Pimp Fill Button

In classical object oriented fashion, you’d reason both the Light and the Button share a base each uses to embed itself within the power panel. From there both the Light and Button would go on to have distinct properties and methods.

In JavaScript, this base class would be modeled like this:

var Base = (function() {
function Base(id) {
console.log("base: " + id);
this.id = id;
}

Base.prototype.drawTerminal = function() {
console.log("drawTerminal");
};

Base.prototype.getId = function() {
console.log("Id: " + this.id);
return this.id;
};

return Base;
})();

There are a couple of really cool things at work here. Let’s take some time to look at each.

First, you’ll notice the class is defined using an anonymous self executing closure which returns its class signature after it is defined. The closure encapsulates the details of the class. But, it also turns the class signature into a kind of namespace, thereby preventing class properties and methods from polluting the Global Namespace.

Second, you’ll notice the class has a bonafide constructor you can use to setup the class instance. All methods of the class extend the prototype chain of the class: Class.prototype.* Lastly, we return the class definition - it will be your class’ interface to the world.

You could easily create a new instance of the base class:

var base = new Base("123456");

But, that wouldn’t be too useful. And that’s fine because it’s not meant to be too useful. The base class is just that, a base class (with base functionality) from which most other classes will inherit from. Here, the base’s primary function is to simply drawTerminal because everyone will need a Terminal in order to connect to the Power Panel.

JavaScript Inheritance And ALL THE THINGS

Getting Started with JavaScript Inheritance

Things really get interesting when you want to create a Light that inherits from the base class. But, what’s the best way to accomplish classical inheritance in a prototypical world?

One of the most interesting ways to achieve classical inheritance in JavaScript is to do the following:

var Light = (function(_super) {

function Light(id, color) {
_super.call(this, id);

this.color = color;
console.log("Start Light: " + color);

_super.prototype.drawTerminal();
}

Light.prototype.setColor = function(color) {
this.color = color;
console.log("Change Light: " + color);
}

Light.prototype.getColor = function() {
console.log("Color: " + this.color);
return this.color;
}

return Light;
})(Base);

The first thing you’ll notice is we passed the parent class into the self-executing closure. This then becomes the super object reference in the anonymous function. The parent constructor and methods are access through the super object.

In particular, to call the parent’s constructor, simply execute:

_super.call(this, id);

Function.call calls a function with a given this value and the arguments provided individually. You can use call to chain constructors for an object. Here, this refers to the current object, the calling object. Next, you can supply as many arguments as your parent’s constructor demands.

Access to the parent’s methods are done through the prototype chain:

_super.prototype.drawTerminal();

This is pretty powerful stuff! You have things you’d never dream of in JavaScript:

1. Parent Constructor Reuse

2. Parent Method Inheritance

All the things that make your code more maintainable.

JavaScript Multiple Inheritance

If you ever need to, this technique also opens the door for Multiple Inheritance in JavaScript. Consider the following:

var Light = (function(_super1, _super2) {
function Light(id, color) {
_super1.call(this, id);
_super2.call(this, id, color);

. . .
}

. . .

return Light;
})(Base, AnotherClass);

JavaScript child classes can inherit from as many parent classes as needed. It goes without saying to be judicious when inheriting from multiple classes. But, if you ever need to, JavaScript is more than flexible enough to accommodate that need.

CoffeeScript: In Too Deep

Still with me? Excellent!

Up until this point, your freshly minted Light Class can call it’s parent constructor and call methods on its parent class. But, you haven’t actually inherited anything.

That is to say, the methods of the Base Class are not present on the prototype chain for the Light Class.

If inheritence worked, the Light Class would have four methods on the prototype chain. Two from the parent: drawTerminal and getId. The remaining (from itself): setColor and getColor.

Yet, only the Light Class methods exist:

JavaScript Light Class Before CoffeeScript Extends

Not a complete loss. You could still write wrappers over the parent methods. After all, you still have access to _super. But, for large code bases, this can become unmaintainable. Better if child instances just magically had access to parent methods.

That’s where CoffeeScript’s Extends method comes into play:

var __hasProp = {}.hasOwnProperty;
var __extends = function(child, parent) {
for (var key in parent) {
if (__hasProp.call(parent, key))
child[key] = parent[key];
}

function ctor() {
this.constructor = child;
}

ctor.prototype = parent.prototype;

child.prototype = new ctor();
child.__super__ = parent.prototype;

return child;
};

CoffeeScript Extends method does a deep copy of parent methods unto the child prototype chain. Even better, using CoffeeScript Extends method is easy. Simply pass the child class as the first argument and the parent class as the second argument:

var Light = (function(_super) {
__extends(Light, _super);

function Light(id, color) {
_super.call(this, id);

this.color = color;
console.log("Start Light: " + color);
//_super.prototype.drawTerminal();
this.drawTerminal();
}

Light.prototype.setColor = function(color) {
this.color = color;
console.log("Change Light: " + color);
}

Light.prototype.getColor = function() {
console.log("Color: " + this.color);
return this.color;
}

return Light;
})(Base);

The result is parent methods are accessible in the child class without having to rewrite those same methods:

JavaScript Light Class After CoffeeScript Extends

This time when we count we get the four expected methods: drawTerminal, getId, setColor and getColor. Which is great because an instance of the child class can access the parent method with ease:

    var light = new Light("LABC123", "Red");
light.getId();

This cuts down on the potential for much code duplication. Also, it’s simply pleasant to use. You still call the parent constructor using the _super.call route. But, this time you can access the parent methods within the current scope. Lastly, instances of the Light class magically have access to those parent methods as well.

JavaScript Inheritance: Final Thoughts

JavaScript is a beautiful and inspiring language. It’s a first class language with all the expressiveness of a functional language and the organization of an object oriented language. It is that dual nature that makes her so intriguing and yet, undeniable.

The time has come to recognize and celebrate both. Back in days long past, I too longed for organized class structures in JavaScript. Lo’ and Behold, they were always there to begin with and now you have them too.

Inheritance has always been a tricky subject in JavaScript. Simply put, the language doesn’t provide a keyword for inheritance. Yet, JavaScript is expressive enough to provide a plethora of mechanisms to achieve inheritance. This is the fertile ground of innovation I so vigorously profess.

Yet, many a language and community is ripe for innovation. Each standing at its pinnacle, poised for the future. So what makes JavaScript so enduring, yet so delectable? Us…

discuss on twitter


every day thousands of developers use our charts & gauges to get the job done right

JavaScript Charts JavaScript Gauges JavaScript Flight Gauges


← return to all articles