JavaScript Inheritance

Here at harmonize, we think about languages a lot. Usually not for any good reason, but when you are writing code for as many hours as we do, you tend to think about how it might be easier or cleaner if the language did things a little bit differently.

One thing I’ve thought a lot about recently is inheritance in JavaScript. We use the ExtJS library, which is an outstanding JavaScript library. Inside of this library is a mechanism for achieving inheritance in JavaScript. It’s pretty simple, and is essentially just a nice wrapper for manipulating standard JavaScript function prototypes. For instance, to extend the Ext.Panel class to check to make sure the ‘neveradd’ component is never inserted into a panel, you would do the following:

NewClass = Ext.extend(Ext.Panel, {
    add: function(component) {
        if (component.id != 'neveradd')
             NewClass.superclass.constructor.call(
                 this, component);
       }
   }
});

A bit silly, perhaps, but you get the idea. NewClass is exactly the same as Ext.Panel except for the overridden add function.

At harmonize we have been very strict about making object members public. Usually we will only assign a function to “this” if it will be needed by an external object. This makes our code safe and non-cluttered. When you look at an object, you only see the members you’re supposed to be using. A trivial example is below.

function MyClass() {
     //This is private by virtue of lexical scoping
     var myvar = 1;
     this.member = 2; //this is public
 
     /* This is private. */
     function private_method(arg) {
           //Do private stuff ;)
     }
 
     /* This is public */
     this.method = function(value1, value2) {
          //Do stuff
     }
}

However, as I deal more with inheritance, I’m beginning to see flaws in this model. For one, because private functions are lexically scoped, there is no way for a derived class to override its parents private functions. This is generally bad. Sometimes you might want to ensure nobody ever touches a function for any reason, but it’s rare that a programer has the insight to say with confidence “This function will never in the history of the world need to be overridden for any reason”.

In addition, because lexically scoped functions are recreated every time an instance of the object is constructed, they end up using far more memory. The Ext inheritance system uses function prototypes in the background, which means that any function that is not overridden is used by every instance of a class. Functions that are not overridden are not created more than once.

So we’ve happened upon some of the fundamental limitations of JavaScript. It’s very difficult to implement an efficient, clean inheritance system in JavaScript. It’s unfortunate, but as memory consumption and our own flexibility become increasingly important at harmonize, I will probably be creating classes in the Ext style more and more.

Tags: ,

blog comments powered by Disqus