I understand implementing JavaScript overloading based on arguments object, or by explicit checking type of and length of arguments.please explain this article: http://ejohn.org/blog/javascript-method-overloading/.
-
4What part do/don't you understand? It's not really an appropriate question for StackOverflow. I don't mean to be pedantic, but this site is geared around specific technical questions. For grasping an understanding of general topics, it's too broad. Maybe e-mail the author and ask him? [email protected]user1017882– user10178822015-01-27 09:54:09 +00:00Commented Jan 27, 2015 at 9:54
-
Explaining which part doesn't make sense will allow us to give you a focused answer rather than explaining every single details. Also, make sure you step through the code using a debugger.Ruan Mendes– Ruan Mendes2015-01-27 09:56:08 +00:00Commented Jan 27, 2015 at 9:56
-
Closures is the key. Take a look at this: w3schools.com/js/js_function_closures.aspHoijof– Hoijof2015-01-27 10:01:18 +00:00Commented Jan 27, 2015 at 10:01
Add a comment
|
1 Answer
There are two concepts in the function below that I think could be the source of your confusion.
addMethodkeeps a reference to previously added function as a closure stack usingvar old = object[name];.addMethodknows how many arguments a function was defined with usingFunction.length(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/length) and compares that with the closure stack it creates. If it doesn't match, it goes up to the next one(); That's what John Resig is referring to as the overhead this method creates.
The logging created by the code below should help you see what's happening.
// addMethod - By John Resig (MIT Licensed)
function addMethod(object, name, fn) {
var old = object[name];
object[name] = function() {
if (fn.length == arguments.length) {
console.log('Arguments and parameters count are the same, found the function');
return fn.apply(this, arguments);
}
if (typeof old == 'function') {
console.log('Arguments and parameters count are not the same, try the next function in the closure stack');
return old.apply(this, arguments);
}
};
}
function Users() {
// This will be at the bottom of the stack, every call will have to go through the functions below
addMethod(this, "find", function() {
console.log('Called with 0 arguments');
});
// This will be at the middle of the task
addMethod(this, "find", function(name) {
console.log('Called with one argument');
});
// This is the one with the least overhead
addMethod(this, "find", function(first, last) {
console.log('Called with two arguments');
});
}
var users = new Users();
users.find();
users.find('John');
users.find('John', 'Resig');
Remember to step through functions when trying to understand them. Right click on the image below and choose "open image in new tab"

Here's an addMethods will a little less overhead and IMHO, nicer syntax and less repetition.
// addMethods - By Juan Methods, inspired by John Resig (MIT Licensed)
function addMethods(object, name /* fn, fn, fn ... */ ) {
// Key is the parameter count for each passed in function, value is the function itself */
var functionMap = {};
for (var i = 2; i < arguments.length; i++) {
functionMap[arguments[i].length] = arguments[i];
}
object[name] = function() {
functionMap[arguments.length].apply(this, arguments);
};
}
function Users() {
// Now every function has constant overhead of a single map lookup, which
// is less expensive than multiple method calls up the closure stack
addMethods(this, "find",
function() {
console.log('Called with 0 arguments');
},
function(name) {
console.log('Called with one argument');
},
function(first, last) {
console.log('Called with two arguments');
}
);
}
var users = new Users();
users.find();
users.find('Jack');
users.find('John', 'Resig');