X

Sundararajan's Weblog

  • Java
    November 8, 2005

Multiple inheritance in JavaScript

Guest Author
We saw similarities between Self and JavaScript in my post titled
Self, JavaScript and JSAdapter. One important difference between JavaScript and Self is that Self supports multiple inheritance. Self supports more than one parent slots per object. Note that parent slot of Self is similar to JavaScript's prototype (settable by __proto__ property). But, in JavaScript, there is only one rototype per object. So, how do we have multiple inheritance in JavaScript? We can use JSAdapter.
We will code a JSAdaper based 'extend' function for multiple inheritance (I'd have preferred 'extends' -- but that is a reserved word in JavaScript!)

// first parameter is the object extended.
// rest of the parameters are 'super' objects.
// or in Self terminology, multiple 'parent' slot values.
function extend(object /\*,proto1, proto2, ....\*/) {
if (arguments.length < 2) {
throw "should extend from atleast one proto";
}
// collect all prototypes in an array
var protos = new Array(arguments.length - 1);
for (var i = 1; i < arguments.length; i++) {
protos[i-1] = arguments[i];
}
// save the first param as 'self'
var self = object;
self.__proto__ = new JSAdapter() {
// check the property in all prototypes
__has__: function(name) {
for(var i in protos) {
if (name in protos[i]) {
return true;
}
}
return false;
},
// check the property in all prototypes
__get__: function(name) {
for(var i in protos) {
if (name in protos[i]) {
var p = protos[i];
var prop = p[name];
// treat function type properties differently
if (typeof(prop) == 'function') {
// we need to make the 'this' to be the 'self'
return function() {
return p[name].apply(self, arguments);
}
} else {
return prop;
}
}
}
return undefined;
},
__put__: function(name, value) {
for(var i in protos) {
if (name in protos[i]) {
protos[i][name] = value;
return;
}
}
},
__delete__: function(name) {
for(var i in protos) {
if (name in protos[i]) {
delete protos[i][name];
return;
}
}
},
__getIds__: function() {
var res = new Array();
for (var i in protos) {
for (var j in protos[i]) {
res[res.length] = j;
}
}
return res;
}
}
return self;
}

Using the above extend function, we can use multiple inheritance as shown below:

var x = { b : 10, f: function() { print(this.b); } }
var y = { a : 12, add: function() { return this.b + this.a } }
var m = new Object;
extend(m, x, y);
print(m.b); // prints 10
print(m.a); // prints 12
m.f(); // prints 10 by calling x.f
print(m.add()); // prints 22!
m.a = -2;
print(m.add()); // prints 8!

Wow! We really got multiple inheritance in JavaScript! Now, you may want to write
reusable mixins in JavaScript!!

Be the first to comment

Comments ( 0 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.