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
Mar
22
2010

Javascript Inheritance

In this post I will cover the following topics:

  • Understanding how the prototype works
  • Using the prototype for inheritance
  • The Inherit Function
  • Overriding methods

In one of my previous post i talked about Object Oriented Javascript , where i mostly talked about class encapsulation. In this post i would like to advance to another important issue of object oriented – inheritance.

In Javascript inheritance is not that straightforward as it is in most object oriented languages, where a simple keyword will allow you to inherit from a class. In Javascript you need a several steps in order to achieve inheritance. Moreover, Javascript’s inheritance is prototypal. The language flexibility allows you to use standard class based inheritance, or a more complex prototypal inheritance (which I will not get into in this post).

Standard Inheritance

First lets declare a simple function to be used as a base class:


/*Class Animal*/
function Animal(name){
    this.name = name;
}

Animal.prototype.getName = function(){
    return this.name;
}

Now to create an instance of the Animal class we invoke the constructor with the new keyword:


var monkey = new Animal("monkey");
alert(monkey.getName());

Now we will create a class that inherits from the Animal class:


/*Class Monkey*/
function Monkey(name,specie){
    //call the superclass constractor in the scope of this
    Animal.call(this,name);
    this.specie = specie ;
}

Monkey.prototype = new Animal(); //prototypal chain
Monkey.prototype.constructor = Monkey; //set the constructor to Monkey
Monkey.prototype.getSpecie(){
    return this.specie;
}

Now let’s go over about what just happened here:
First we created a constructor function as we did with the Animal class, but this time we called the superclass constructor using the call method and passed the name argument. When we create a new instance of Monkey the Javascript engine creates for us an empty object and runs the constructor with this empty object, where this refers to this empty object. in order to do the same for the superclass we do it manually with the Animal.call(this,name); that will invoke the Animal constructor with the empty object.
After that we set up the prototype chain. Let’s explain what that means first. In Javascript, the prototype attribute points to either another object or null. When a member of an object is accessed, Javascript looks for this member in the prototype object if it doesn’t exist in the current object. It will continue to go up the chain of prototype until it will find or the prototype will be null.

To set up the prototype chain we set the prototype to a new instance of the superclass: Monkey.prototype = new Animal();
When we set the prototype attribute to an instance of Animal, the constructor attribute is deleted; this is why we need to set the constructor attribute back to Animal.
To create an instance is the same as it used to be:


var monkey = new Monkey("monkey","orangutan");
alert(monkey.getName());
alert(monkey.getSpecie());

Inherit Function

We could wrap all this inheritance code into a function to help us. I came across this implementation on the web, and I added to my own library, but I can’t remember where I took it from. Anyway it’s a cool code to use, and I’ll explain how it works:


function Inherit(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;
    }
}

Now we can do the following:


/*Class Monkey*/
function Monkey(name,specie){
    //call the superclass constractor in the scope of this
    Monkey.super.constructor.call(this,name);
    this.specie = specie ;
}

Inherit(Monkey,Animal);

I will explain now about the Inherit function since it covers some important issues.
The function does the same things that we did manually, except the following:

  • Adds the empty class thinF – This is done to increase performance. Since we need to create a new instance of the super to be set to the prototype for the sub class, we (usually) don’t want to instantiate a new instance, since we only need the prototype of this class, so we save some memory and CPU this way.
  • Saves the super prototype – this way we can call the constructor without knowing the name of the super.

Overriding Methods

Overriding is pretty simple, you just need to declare the method name again in the sub class. If we use the Inherit function we can also call the super implementation since we have the prototype of the super:


Monkey.prototype.getName = function(){
    var name = this.specie + " is a " + Monkey.super.getName.call(this);
    return name;
}
Bookmark and Share
Feb
21
2010

Debugging Firefox Extension Using Log File

Problog

In this post I will cover the following topics:

  • Understanding debug requirements
  • Using the Mozilla preferences service to store debug mode
  • Using Mozilla file I/O to write debug messages into a file

In one of me recent post I’ve talked about how to setup a development environment in Firefox. One of the problems in developing firefox extensions and i think software in general is how to debug a problem occurring on client machine that is unreproducible at the development side.

It’s hard enough to debug firefox extensions locally;  to try and understand what happened on a remote machine is very difficult. To debug on the local side I usually prefer to log information to the Firebug console as a mechanism to trace what is going on inside my Firefox extension. I know many developers just use an alert as the best way to debug but it’s synchronous.  Also it doesn’t scale, for example to debug a loop of 1000 elements. It’s not that I never use the alert function for debugging.  I often use it, but only for unit testing and occasionally functional testing.  In order to understand what’s going on at a system-wide level, I think the console is the best choice, at least for now.

I’m working on a cool firefox extension right now, and wanted to share the debug object i wrote – DebugObj.

Debug Object Requirements

First of all, I wanted to control the mode of the debug object. i decided to implement 3 modes:

  • console – writing debug string into the console. I will use this mode for my own debugging.
  • file – writing debug string into a local file. This mode will be used when a remote machine is having a problem and we want to see some inside stuff going on.
  • none – the debug object is not doing anything. this will be the default release version in order to save unnecessary calls to the console and file.

I also wanted to a way to change the debug mode in an easy and persistent way.

Debug Object Implementation

First let’s start by defining the debug object and setting some properties to it:


var debugObj = {
    mode: "none",
    isInit: false,
    consoleService: null,
    file: null,
    foStream: null,
    converter: null
};

The mode property states the debug mode of the object and the isInit states if we are ready to start writing debug messages. We will get into the other properties later.
Now let’s take a look on the init method:


init: function(){
    if( debugObj.isInit ) return;
     var pref = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService).getBranch("extensions.myextensionname.");
    debugObj.mode = pref.getCharPref("DebugMode");
    debugObj.consoleService = Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService);

    if( debugObj.mode == "file" ){
        debugObj.file = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties).get("Home", Components.interfaces.nsIFile);
        debugObj.file.append("myextension_debug.log");

        debugObj.foStream = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);

        // use 0x02 | 0x10 to open file for appending.
        debugObj.foStream.init(debugObj.file, 0x02 | 0x08 | 0x20, 0666, 0);

        // if you are sure there will never ever be any non-ascii text in data you can
         // also call foStream.writeData directly
        debugObj.converter = Components.classes["@mozilla.org/intl/converter-output-stream;1"].createInstance(Components.interfaces.nsIConverterOutputStream);
        debugObj.converter.init(debugObj.foStream, "UTF-8", 0, 0);
        debugObj.converter.writeString("------------------------------------------------------------------------\r\nDEBUG STARTS - "+Date()+"\r\nBrowser Info:"+window.navigator.userAgent+"; running on "+window.navigator.oscpu+" "+window.navigator.platform+";\r\nlanguage: "+window.navigator.language+"; "+window.navigator.appVersion+"\r\n------------------------------------------------------------------------\r\n------------------------------------------------------------------------\r\n");

    }
    debugObj.isInit = true;
},

First i try and see if we are already init, then nothing needs to be done. Then i try to read from the preferences service what the current mode is.
I used the preferences service because i wanted to allow the end user to be able to turn on the debug mechanism using the about:config in firefox. Next i get the interface for the console service and store it in the object properties. The i check if the mode is file, i print a welcome debug msg about the browser environment, so i will know when reading the file the OS and version of the browser (usually its very helpful).
Now lets see the main funtion – log:


log: function(msg){
    if( debugObj.isInit == false ) debugObj. init();
    if( debugObj.mode == "console" ) debugObj.logConsole(msg);
    if( debugObj.mode == "file" ) {
        debugObj.logConsole(msg);
        debugObj.logFile(msg);
    }
},
logConsole: function(msg){
    debugObj.consoleService.logStringMessage(msg);
},
logFile: function(msg){
    var d = new Date();
    debugObj.converter.writeString("["+d.toLocaleTimeString()+":"+d.getMilliseconds()+"]"+msg+"\r\n--------------------------------------------------------------------------\r\n");
}

as you can see, the log method make sure we are initialized, and according to the mode call the proper method.

I also added a release method to be call when the application is going down, for proper cleanups:


release: function(){
    if( debugObj.converter )
        debugObj.converter.close();
},

Thats it!

Using Debug Object

Now just call the log file wherever you think is needed like so:


debugObj.log("something interesting that shows a variable="+my_variable);

If you get a bug from a client, just tell him to change the preferences in the about:config to mode=file and to send you the log file with all your debug messages planted in the code.  Since i created an nsIFile interface with the “Home” parameter, the file will be written to “root” directory. I think this is OS specific, so in my case – WS7 – the file was located at c:\user\amir

Bookmark and Share
Feb
16
2010

Object Oriented Javascript

Problog

This post will cover the following topics:

  • Javascript is not a toy!
  • How to define a class
  • How to set Publich methods
  • How to set Private variables
  • How to set static methods

JavaScript for Dummies?

Programming languages are like football teams – it doesn’t matter which you like, you will support it and protect its interest no matter what. Back in the days when i was young, I remember the same old discussion between two development teams where i used to work – C++ vs. Delphi. I guess its an endless discussion where the people and the languages change but the content basically stay the same.
What’s weird is that when i talk to fellow developers about JavaScript i get a weird feeling that everybody looks at it as more of a toy rather than a powerful client side development tool. The major critic that i get is this is a very simple functional language, that cannot match to the object oriented concept that drive most languages. One friend even told me that this is a language for bored teenagers.
I agree – JavaScript is an easy to learn language, but that doesn’t mean that it’s a simple one. I see it as a positive thing that you can quickly achieve your goals without needing to know all the language capabilities, and you can learn very fast how to really use the language capabilities to accomplish things even better or faster.
I decided to show how you can shape JavaScript to be used as an Object Oriented language. I don’t think that you must code JavaScript always in object oriented style, but you should have this ability and choose when you think it’s the best solution to implement.

In this post i will focus on the basics of Object Oriented programming – public, private and static declarations.

Defining a Class

In Javascript everything is an object, even functions. In order to define a new class we should just define a new function like so:


function Player(url){}

No in order to create an instance of this class we can write the following:


var player1 = new Player("http://youtube.com/...");

This line of code will create a new instance of the function object and return the reference to it. Not to confuse, but if the function return a value it won’t be placed in player1. for example, let’s say you have a function like so:


function f1(){ return 100;}
var a = f1();
var b = new f1();

The difference between the two is that a will be assigned with 100 while b will be assigned with the reference to a new f1 function object.

Public Methods

As in any object oriented language, the first thing you would like to do is define some public methods for your class. In Javascritp we will use the prototype keyword to setup new methods for this class. You can do this like so:


function Player(url){
}

Player.prototype.start = function(){
//...do some stuff here...
}
Player.prototype.stop = function(){
//...do some stufff here...
}

For those of you who prefer to create classes encapsulated in one declaration you can also write the same code as so:


function Player(url){
}

Player.prototype = {
    start: function(){
        //...do some stuff here...
    } ,
    stop: function(){
        //...do some stuff here...
    }
};

These two declarations achieve the same result. This is part of the reasons that i love javascript so much – it can be so simple and so complicated at the same time.
Now you can use the class methods as so:


var player1 = new Player("http://youtube.com/...");
player1.start();
player1.stop();

Public Variables

In order to set public variables we will use the this keyword that allow us to preserve state for our object.


function Player(url){
    this.url = url;
}

Now we have a public variable that can be accessed using the class properties as so:


var player1 = new Player("http://youtube.com/...");
player1.url = "http://youtube.com/differenturl";
player1.start();

Usually it is bad practice to allow access to the class inner variables, and such variables needs to be set private.

Private Variables

In order to create private variables we would simple declare them in the constructor as so:


function Player(url){
    var m_url = url;
}

Now the variable m_url is not accessible to anyone. Well that doesn’t make sense, right? We want to allow our public methods to access the data.
We solve this using closure. A closure is a protected variable space, created by using nested functions. In order to better understand it we first need to understand how JavaScript function declaration works. Function declaration in Javascritp is based on two main concepts: lexically scoped and function-level scope. Lexically means that function run in the scope they are defined in and not in the scope they are executed in, as other language usually do. Function-level means, like most languages, that a variable declared in function is not accessible outside that function. Using these concepts we can now declare our private variables that will be accessible to our public methods:


function Player(url){
    var m_url = url;
    this.start = function(){
        //now i can access m_url
    };
    this.stop = function(){
        //now i can access m_url
    }
}

The difference between this code and the previous ones, is that the public methods were declared using the prototype while now they are declared using the this keyword. The main difference is in the way the JavaScript engine execute this code. When declaring functions using the prototype, the Javascript engine creates only one instance of the function in memory and dynamically assigns the this according to the calling object. On the other hand, when declaring a method inside the object constructor, as we did in the last example, the JavaScript engine will create a copy of that function in memory for every instance that you create from the Player class. Usually this shouldn’t be a big factor, but its important to know the difference.

Static Methods & Variables

Using closures and the prototype characteristic i mentioned above you can also create static methods like so:


function Player(url){
    var m_url = url;
    this.start = function(){
        //now i can access m_url
    };
    this.stop = function(){
        //now i can access m_url
    }
    var static_int = 0;
    Player.prototype.getStatic = function(){ return static_int;};
    Player.prototype.setStatic = function(v){ static_int = v; };
}

var p1 = new Player();
var p2 = new Player();
p1.setStatic(100);
alert( p2.getStatic() ); //will print 100.

I hope this example shows the power of JavaScript once you understand how to shape it to whatever you need. I the next post I will show how to implement interfaces and inheritance in Javascript.

Update

I got a comment about the static variable implementation, that there is a bug there. I checked it and there is a bug with the way i set the static variable. in order for it to be static we also need to declare it using the prototype as so:


Player.prototype.tatic_int  = 0 ;
Player.prototype.getStatic = function(){ return static_int;};
Player.prototype.setStatic = function(v){ static_int = v; };
Bookmark and Share
Feb
09
2010

Setting a Nested Object with a String Key

In one of the projects that I’m working on I had to setup a property of an object in a general way. In order to do so, i wrote the following function:


function setValue(key,value,obj){
    obj[key.toString()] = value;
}

so calling the functuion like so


var obj = { a:1,b:2,c:3 };
setValue( "a" , 2 , obj );

will result obj.a to be 2.
But while developing this project my client had to make some changes and the object that i  expected in the function is now a nested object like so:


var obj = { a:1, nested: { b1: 2, b3: 3} , c: 4};

Clearly using my original setValue method wouldn’t work


setValue("nested.b1", 2, obj); //Error!

In order to solve this i used a little trick with recursion:


function setValue(key,value,obj){
    var keys = key.split(".");
    if( keys.length == 1 ){
        obj[key.toString()] = value;
    }
    else{
        var innerObj = obj[keys[0]];
        keys.shift();
        var updatedKey = keys.join(".");
        setValue( updatedKey, value, innerObj);
    }
}

The function work like so: I always try to split the string in an aaray of strings using the split method. so if i get the following string “a.b.c” i will get an array of strings like so: ["a","b","c"]. The split method will have no affect if the string has no dots in it.

I then check the length of the string array. If it has only one element then i assume that there is no nested assignments and i use the original code i used. But if there is, i get the new nested object using the first element of the array and then i remove this element and create back the string using the join method, and call the function in recursion with the nested object.

Now i can use this function in the following way:


var obj = { a: { b: { c: 0 } } };
setValue("a.b.c" , 1 , obj ); // obj.a.b.c = 1

Now my client is happy and i got another cool post.

Bookmark and Share
 
Powered by Wordpress and MySQL. Theme by openark.org