Nicolas Petton

Nicolas Petton

Web developer, Lisper, Smalltalker & Emacs maniac.

A simple object model in JavaScript (part #2)

A simple object model in JavaScript part #2

Feb 22, 2016

In my previous post, I wrote about an approach to class-based OO in JavaScript. I mentioned class extensions (the ability to reopen and extend classes from the outside of the class definition) without showing how that can be done.

An example

Let's take the same animal example as before:

var animal = object.subclass(function(that, spec, my) {

    that.initialize = function() {
        my.name = spec.name;
    }

    that.getName = function() {
        return my.name;
    };

    that.isAnimal = function() {
        return true;
    }
});

var dog = animal.subclass(function(that, spec, my) {

    that.getName = function() {
        return 'dog named' + that.super.getName();
    };
});

In this examlpe, it would be nice to be able to "reopen" the object class from within the file defining animal to extend it, like the following:

object.extend(function(that, spec, my) {
    that.isAnimal = function() {
        return false;
    };
})

The above example shows how useful class extensions can be: it makes it trivial to extend existing classes – and for instance make them polymorphic with your domain, without having to change existing classes' source code.

The implementation is quite straightforward:

object.extensions = [];

object.subclass = function(builder) {
    var that = this;

    function klass(spec, my) {
        spec = spec || {};
        my = my || {};

        var instance = that(spec, my);

        instance.class = klass;

        // access to super for public and protected properties.
        instance.super = Object.assign({}, instance);
        my.super = Object.assign({}, my);
            
        that.extensions.forEach(function(extension) {
            extension(instance, spec, my);
        });
            
        builder(instance, spec, my);
        instance.initialize();
            
        return instance;
    }
            
    // static inheritance
    Object.assign(klass, that);
        
    klass.subclasses = [];
    that.subclasses.push(klass);
        
    return klass;
};

object.extend = function(builder) {
    this.extensions.push(builder);
};

There are several other improvements that can be made, but in the meantime head over to GitHub if you want to grab the source code.

comments powered by Disqus