Dynamic inheritance?


Chris Double has some nice examples over on his blog for using dynamic inheritance in Self and Io. As JavaScript is similar to Self and Io (as far as it also has a prototypical object system) Chris mentions with regards to JavaScript:

JavaScript is also a prototype based programming language. Unlike Self or Io it only allows one object to be used as the prototype in any given object. This is stored in a hidden ‘__proto__’ member and cannot be updated once set on construction (some implementations allow changing it however). Objects are created by using the ‘new’ keyword on a constructor function that initializes the object. For now I’ll leave it as an exercise for the reader to implement the examples above in JavaScript. I’d be interested in the approaches people take.

So, interested at seeing how I might approach this I sat down to recreate the Self example in JavaScript without resorting to manipulating __proto__ which isn’t in the spec and will not work cross-browser.

Failed miserably.

Without multiple inheritance and with the prototype reference locked in for the life of the object I only ended up chasing code down rabbit holes.

Finally, in desperation I settled on what I thought was the least crappy option:

// In the absense of ES5's Object.create
function object(o) {
    function F() {}
    F.prototype = o;
    return new F();
}


var file = (function () {  
    
    var that = {
        close: function () {
            console.log("closing");
            this.close = null;
            this.open = that.open;
        },
        open: function () {
            console.log("opening");
            this.open = null;
            this.close = that.close;
        }
    },
    stub = object(that);
    
    stub.close();
    
    return stub; 
}());


var myFile = object(file);
myFile.open();  
myFile.close(); 
myFile.open(); 


var myFile2 = object(file);
myFile2.open(); 

Whilst the prototype link may be fixed at construction I know that in JavaScript all the “user” object properties are dynamic and able to be set (unless it’s ES5 and the object has been frozen or the property been made non-writable) - meaning that I can dynamically turn properties “on” and “off” as needed.

This only superficially achieves the results of the example by switching functions in and out of slots on this, it does not give a flexible prototypes with traits system as outlined in Ungar’s Organizing Programs Without Classes paper. However, JavaScript is a flexible language and it wouldn’t be all that hard to implement something more sophisticated that would get the desired effect. Unfortunately, as with attempts to foist class systems onto JavaScript the end result is typically kludgy and the resulting code built on top of such an approach would not be idiomatic JavaScript.

Sure, multiple inheritance and dynamic inheritance is powerful in Self and might have gone nicely with JavaScript’s prototypical objects but they aren’t there and trying to get too clever in a scripting language can make you Br’er Rabbit stuck to a tar baby. I think that in JavaScript it’s best to stick to a shallow inheritance hierarchy that doesn’t use traits and use other compositional techniques that feel more natural to the language.

That said, somebody else may have a particularly elegant way to do this that I have completely missed. If so, I’d definitely like to see it.



CoffeeScript in Action


CoffeeScript in Action book cover

I'm the author. Get it from Manning.