If you are one of those hard core javascript developers who are actively developing OO style javascript, how many times would you have to override an existing method on a js class to extend the functionality ? I bet the answer would be very often. I had to tackle this many a times, but in the process wanted to write a basic utility that did the work for me as well as save the reference to the original method. Going a step further, I wanted to be able to replace a method multiple times but still maintain the chain of super methods ( similar to java inheritance ).

Here is my extendMethod() utility

 
//NoOp Method
var emptyMethod = function(){
	return this;
}  
 
//Extend Method utility  
var extendMethod = function(target, methodName, func){
 
    //Save the super method
    func.base = target[methodName] || emptyMethod;
 
    //Replace Method with new one
    target[methodName] = func;
 
}

Consider this example:

 
// Introduce log() method on Object
extendMethod(Object.prototype, "log", function(){
	console.log(this.toString(true, true));	
 
});
 
//Extend toString() on Object to support JSON
extendMethod(Object.prototype, "toString", function(json){
	return json && window.JSON
		? JSON.stringify(this)
		: arguments.callee.base.apply(this, arguments);
});
 
//Further extend toString() on Object to support log format
extendMethod(Object.prototype, "toString", function(json, log){
 
	return log
		? [ "MyApp", arguments.callee.base.apply(this, arguments) ].join(" : ");
		: arguments.callee.base.apply(this, arguments);
});

Note: Make sure this piece of code is called only once in your browser environment.

Now that we have extended the toString method on Object, Run this sample code.

 
var a = { flag: true, value: "myself"}
 
console.log(a.log())
//Output => MyApp : {"flag":true,"value":"myself"}
 
console.log(a.toString())			
//Output => [object Object]
 
console.log(a.toString(true))		
//Output => {"flag":true,"value":"myself"}
 
console.log(a.toString(true, true)) 
//Output => MyApp : {"flag":true,"value":"myself"}

Now we have the power to extend the method on an prototype mutliple times but not loose the original functionality. In addition, keeping the reference chain is a bonus. :)

Hope you enjoyed this piece of code. I definitely did.