Hoc Class Interface

Basic implementation of Hoc interface of simplified classical class inheritance in Javascript.

by klenwell

HTML

<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-1.12.0.css">
<script src="http://code.jquery.com/qunit/qunit-1.12.0.js"></script>
<div id="qunit"></div>  
<div id="qunit-fixture"></div>

JavaScript

console.debug('start');

function Hoc() {
    var self = {};
    self.hoc = this;
    self.ancestors = [];
        
    self.extend = function(hoc) {
        self.ancestors.push(self.hoc.constructor.name);
        self.hoc = hoc;
        return self;
    };
    
    self.is_a = function(ObjType) {
        return (self.equals_a(ObjType)) ? true :
            self.ancestors.indexOf(
                ObjType.prototype.constructor.name) >= 0;
    };
    
    self.equals_a = function(ObjType) {
        return self.hoc instanceof ObjType;
    };
    
    return self;
}

function G1(foo) {
    var self = new Hoc();
    self = self.extend(this);
    self.foo = foo;
    return self;
}

function G2(foo) {
    var self = new G1(foo);
    self = self.extend(this);
    
    self.bar = function() {
        return 'G2: ' + self.foo;
    };
    
    return self;
}

function G3(foo) {
    var self = new G2(foo);
    self = self.extend(this);
    
    // Override base method
    var super_bar = self.bar;
    self.bar = function() {
        return 'G3: ' + super_bar();
    };
    
    return self;
}

test("Hoc Base Object", function () {
    var hoc = new Hoc();
    ok(hoc.equals_a(Hoc));
    ok(hoc.is_a(Hoc));
    ok(! hoc.ancestors.length);
});

test("First Generation Hoc Object", function () {
    var g1 = new G1('foo');
    equal(g1.foo, 'foo');
    ok(g1.equals_a(G1));
    ok(! g1.equals_a(Hoc));
    ok(g1.is_a(G1));
    ok(g1.is_a(Hoc));
    ok(! g1.is_a(G2));
});

test("Second Generation Hoc Object", function () {
    var g2 = new G2('bar');
    ok(g2.equals_a(G2));
    ok(g2.is_a(G2));
    ok(g2.is_a(G1));
    equal(g2.bar(), 'G2: bar');
});

test("Third Generation Hoc Object", function () {
    var g3 = new G3('baz');
    ok(g3.is_a(G3));
    ok(g3.is_a(G2));
    ok(g3.is_a(G1));
    ok(g3.is_a(Hoc));
    deepEqual(g3.ancestors, ["Hoc", "G1", "G2"]);
    equal(g3.bar(), 'G3: G2: baz');
});