Jun
11
2010

Implementing Multiple Inheritance in Javascript

Update

First of all I have a new logo and favicon – it’s that funky Ninja icon on the top left. It was designed by the gifted designer Liora Darom. I’ll be happy to provide her contact if someone is interested.

It’s been a while since my last post, usually I try to write more often but I had too much on my hands.  One of the cool projects that I worked on is now available, it’s called Web-Exposed. This is a Firefox addon that lets the user see what’s all kind of data about web sites, like Alexa rank, page rank, the owner of the site, and more traffic, SEO and security information. This is one of the cooler things I did in Javascript and 90% of the development was made in pure Javascript (Yipi for the super geek). I think this project deserve a post of its own, so maybe in the next post I’ll write more about the technology inside, but for now you can download and play with it, and I’ll be more than happy to hear from you what do you think and to get some feedback.

Download Web-Exposed



Multiple Inheritance

In the last few days I read and played with PHP 5 object oriented. The more I played with it the more I appreciated the power of Javascript. My dream is to have scalable and powerful Javascript server side engines – a man can dream can’t he? To write the server and the client in the same language, how long do you think that will happen…

Anyway, I wanted to show how flexible the language is and to demonstrate how you can implement multiple inheritance.

Single Inheritance

In my previous post about Javascript inheritance I demonstrated how to use Javascript prototype in order to achieve inheritance.

There is another way to imitate inheritance by cloning all the functions of the super to the sub manually. Lets go over the code:


function Inherit(sub,super){
    var proto = super.prototype;
        for( var f in proto ){
            if( f != "constructor" && typeof proto[f] == "function" ){
                if( sub.prototype[f] == undefined ){
                    sub.prototype[f] = function(){
                        return proto[f].call(this,arguments);
                }
            }
        }
    }
}

As you can see , the function iterate the super prototype and for every function it finds it creates  a matching function in the sub prototype. I added the “constructor” condition since usually the constructor is a regular property of the prototype object with the DontEnum flag  so it doesn’t show up in for..in  loops, but developers can override the constructor and when they do the DontEnum  is also override, so just to make sure i skip the constructor.

The Extend Function

Combining the prototype inheritance and the method I just explain allows us o create multiple inheritance in Javascript. I created the extend function like so:


function extend(sub){
	var supers = [];
	var single = function(sub,super){
		var thinF = function(){};
		thinF.prototype = super.prototype;
		sub.prototype = new thinF();
		sub.prototype.constructor = sub;
		sub.super = super.prototype;
		if( super.prototype.constructor == Object.prototype.constructor ){
			super.prototype.constructor = super;
		}
	}

	var multi = function(sub,super){
		var proto = super.prototype;
		for( var f in proto ){
			if( f != "constructor" && typeof proto[f] == function" ){
				if( sub.prototype[f] == undefined ){
					sub.prototype[f] = function(){
						return proto[f].apply(this,arguments);
					}
				}
			}
		}
	}

	if( arguments.length < 2 ) return;
	single(sub,arguments[1]);
	supers.push(arguments[1]);
	for( var i=2; i<arguments.length;i++){
		multi(sub,arguments[i]);
		supers.push(arguments[i]);
	}
	sub.prototype.callSuper = function(fnc){
		var len = supers.length;
		for( var i=0;i<len;i++){
			var super = supers[i];
			if( (fnc in  super.prototype) && (typeof super.prototype[fnc] == "function") ){
				return super.prototype[fnc].apply(this,[].splice.call(arguments,1));
			}
		}
		return null;
	}
}

The method takes the sub and as many supers as you want. The first thing it does it to make the sub inherit the first super using the regular inheritance method, which I called single. After that the function loops over all the other supers and copy their methods into the sub prototype object using the multi function.

As an extra bonus I saved all the supers in an array and provided a method to call a super method in case the sub has override it. Let’s see some examples how to use it.


function P1(){}
P1.prototype.p1_talk = function(){
	return "P1 talking ";
}

function P2(){}
P2.prototype.p2_talk = function(){
	return "P2 talking ";
}

function SP(){}
SP.prototype.sp_talk = function(a,b){
	return "sp talking with "+a+" and "+b;
}

function P3(){}
extend(P3,SP);

P3.prototype.p3_talk = function(){
	return "p3_talk";
}

function P4(){}
extend(P4,P3);

var p4 = new P4();

function Son(){}

extend(Son,P1,P2,P3);

Son.prototype.sp_talk = function(){
	return "Son override SP talk ";
}

var s = new Son();
//text = "P1 talking P2 talking Son override SP talk sp talking with a and b"
var text = s.p1_talk() + s.p2_talk() + s.sp_talk()+ s.callSuper("sp_talk","a","b");

I haven’t used this code in any of the project that I’m working on, and developed it as an experiment with Javascript object oriented and to win a bet with a friend – so I won a couple of dollars and you got to read something cool – another win-win post.

Bookmark and Share
Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • E-mail this story to a friend!
  • FriendFeed
  • LinkedIn
  • StumbleUpon
  • Twitter

posted in Blog by Amir Harel

Follow comments via the RSS Feed | Leave a comment | Trackback URL

  • that's all cool js tip for better coding, thank you very much for sharing.
blog comments powered by Disqus
 
Powered by Wordpress and MySQL. Theme by openark.org