Tuesday, 27 August 2013

Inheritance for JavaScript when writing widget libraries

Introduction

On the last day that I worked on the AngularPrime widget library for AngularJS, I was creating some kind of inheritance between JavaScript objects. As I'm coming from a Java background, I'm trying to keep some of the principles of Java to feel me more at home in the other language.
Although strictly speaking, JavaScript doesn't has a inheritance mechanism, there are some possibilities with the prototype object.
In the AngularPrime code, I had several snippets of code that was used for several widgets. And thus I liked to define them only once, as a good practice habit.

Problem description

I was using object literals, as I only needed some functions and didn’t had a need to keep some state.  The main purpose was to keep the code readable in small chunks. And thus object literals seemed to me a very logic solution as you create singletons with them.

So my code looked like this
library.baseWidget = {};

library.baseWidget.common = function(element) {
  // The common functionality
};

library.widget1 = {};

library.widget1.constructWidget = function(element) {
   // Other code and fuction calls.
   this.eventRelated(element);
}

library.widget1.eventRelated = function(element) {
   // widget specific code
   library.baseWidget.common(element);
}

// Code for other widgets


Although this works well, I like to have the call to the common code also by using the this. reference. Just as in Java, that you can define methods in the super class and that all descendants inherited the functionality.

No constructor approach


As I'm not using a constructor for the object instantiation, the best described solution approach can't be used.
And as I searched further, I even found out that it wasn't even possible to assign a certain 'prototype' object to an object instance created by an object literal.

I came across a few StackOverflow messages of people that wanted to do the same and found some code that, adapted a little bit, looked perfect for me.

library.baseWidget = {};

library.baseWidget.common = function(element) {
  // The common functionality
};

library.widget1 = library.core.inheritedFrom(library.baseWidget);

library.widget1.constructWidget = function(element) {
   // Other code and fuction calls.
   this.eventRelated(element);
}

library.widget1.eventRelated = function(element) {
   // widget specific code
   this.common(element);
}

// Code for other widgets

I named the function inheritedFrom to make clear what is the purpose of the code.  By using that function, I'm able to call the common functions by using the this. reference.

The magic function is shown here:
    library.core.inheritedFrom = function (superClass) {

        var subclass = {}
            , F = function (instance) {};
        F.prototype = superClass;

        return new F(subclass);

    };

And as you have no choice then using a constructor approach so that you can assign the prototype object, the function thus this also.  But it is hided and the function nicely indicates what the purpose of the function is.

Conclusion


As you can’t assign a prototype object when you use object literals, I created a function that hides the creation of a new object based on a superclass (as prototype object).