I was reading the book Secrets of the Javascript Ninga and I came accross the addMethod function by +John Resig.
This function keeps a pointer to the old method if it exist (via closure) and overwirtes the method with a new one. This new method compares the function length and the arguments length and if they are equal it calls the method provided otherwise it calls the old method.
So if you add many methods and try to call the one that was added first, it will go through all the methods added and in each it will fall back to the old method because arguments doesn't match the function length, and finally it will land on the first added.
I made an alternative to this function.
This 'addMethod' keeps a cache of the added methods using fn.length as the key, and it calls directly the one whose key matches the arguments.length.
I think this might be slightly faster than John's function, but there is a cache property on the method which might create problems if it is altered.
// addMethod - By John Resig (MIT Licensed) function addMethod(object, name, fn) { var old = object[name]; object[name] = function() { if (fn.length == arguments.length) return fn.apply(this, arguments); else if (typeof old == 'function') return old.apply(this, arguments); }; }
This function keeps a pointer to the old method if it exist (via closure) and overwirtes the method with a new one. This new method compares the function length and the arguments length and if they are equal it calls the method provided otherwise it calls the old method.
So if you add many methods and try to call the one that was added first, it will go through all the methods added and in each it will fall back to the old method because arguments doesn't match the function length, and finally it will land on the first added.
I made an alternative to this function.
// addMethod - By Stavros Ioannidis function addMethod(obj, name, fn) { obj[name] = obj[name] || function() { // get the cached method with arguments.length arguments var method = obj[name].cache[arguments.length]; // if method exists call it if ( !! method) return method.apply(this, arguments); else throw new Error("Wrong number of arguments"); }; // initialize obj[name].cache obj[name].cache = obj[name].cache || {}; // Check if a method with the same // number of arguments exists if ( !! obj[name].cache[fn.length]) throw new Error("Cannot define multiple '" + name + "' methods with the same number of arguments!"); // cache the method with fn.length arguments obj[name].cache[fn.length] = function() { return fn.apply(this, arguments); }; }
This 'addMethod' keeps a cache of the added methods using fn.length as the key, and it calls directly the one whose key matches the arguments.length.
I think this might be slightly faster than John's function, but there is a cache property on the method which might create problems if it is altered.