An alternative to JavaScript's prototypical inheritance

A little bit of history

When I switched my focus from pure PHP backend development over to JavaScript/jQuery frontend development I really had a great time. I developed numerous jQuery plugins for smaller and larger projects alike and had huge amounts of fun progressing so well!

After a while I started to do what I have been doing in PHP for a couple of years now: Reduce every piece of code I write to the bare minimum required and add APIs to it so that anyone can add additional functionality required. That was when I began having a hard time in JavaScript.

At that time I was mainly focused on using jQuery (albeit being quite skilled in vanilla JavaScript) more or less for convenience reasons. Anyone who has written jQuery plugins will most likely agree that these are really good for graphical effects and - more or less - simple things. The moment you start to develop something like a pager or slideshow (or anything that has a state and provides its own methods) you will either build totally weird constructs or use something like the jQuery UI widget factory.

But none of these can really disguise that (in contrast to vanilla) jQuery was not really built to have complex, stateful and extendable plugins.

Meanwhile in the secret room

The jQuery plugins I started working on at that time were "Qoopido Emerge"1 and "Qoopido Lazyimage"2. Emerge is a plugin that enables any jQuery object to fire events when it enters or gets near the visual viewport of a website so you can react on these events. Lazyimage does all that for an image and lazyloads it if an emerge-event occurs for it.

It should be obvious that Lazyimage just adds a tiny little bit of functionality to everything Emerge already does.

Everything I could do within jQuery was to additionally invoke Emerge on every Lazyimage, listen for the events respectively and remove Emerge afterwards. That might sound OK so far (and it even worked), but it felt like it should have been more OOP: Lazyimage should extend Emerge, not invoke it manually.

Straight from the Muppet laboratories

I started to do an extended research - like I always do - on JavaScript OOP and inheritance concepts. And found really great tutorials of how to implement this concept with JS native prototypical inheritance.

But coming from PHP I did not feel quite comfortable with an - at least for me - odd looking notation and slightly different implementation of what I loved so much about PHP. So I decided to dig a bit deeper and came across the concept of JavaScript object inheritance3 which I immediately fell in love with. Although it still is a bit different from what I was used to in PHP it comes very close and feels more "natural".

So I ended up developing a base class for all my OOP/inheritance needs I have been using ever since and which was one of the first components of my growing JS library.

Usage is quite simple and straightforward:

var vehicleClass = qoopido.base.extend({
    category: 'vehicle',
    _constructor: function _constructor() {
        // do some constructor magic
    },
    describe: function describe() {
        return 'I am a ' + this.category;
    }
});

var carClass = vehicleClass.extend({
    type: 'car',
    _constructor: function _constructor() {
        // call parent constructor
        carClass._parent._constructor.call(this);
    },
    describe: function describe() {
        return carClass._parent.describe() + ' of type "' + this.type + '"';
    }
});

var fordClass = carClass.extend({
    manufacturer: 'Ford',
    _constructor: function _constructor() {
        // call parent constructor
        fordClass._parent._constructor.call(this);
    },
    describe: function describe() {
        return fordClass._parent.describe() + ' manufactured by ' + this.manufacturer;
    }
});

var vehicle = vehicleClass.create();
var car     = carClass.create();
var ford    = fordClass.create();

console.log(vehicle.describe());
console.log(car.describe());
console.log(ford.describe());

Qoopido Base can be found in my GitHub repository4 and weighs approx. 1.2kb minified and gzipped. It does not depend on jQuery or any other bigger library. All components of my JavaScript library are dual licensed under the MIT and GPL license.

Feel free to download and use it in your projects but remember to give feedback and report bugs so I can make it even better!