Javascript/JQuery arguments by type
I'm not quite sure if the title is correct because I'm not sure how to describe my question, but basically I'm wondering how jQuery can handle functions that take things like ("Some String", true, function(){})
and ("Some String", function() {})
. IE, it seems like it's an overloaded function, I'd expect the function to be something like
fu开发者_如何学编程nction DoSomething(theStr, theBool, theFunc) {
//...
}
but that doesn't explain how it can handle the 2 argument call, at least to me. Anyone able to explain, or is it just a lot of if/else.
jQuery does type checking or arguments internally, shifting parameters (like a callback, typically at the end) forward if there are no arguments in-between. Let's take for example $.get()
where the data
argument is optional, the signature looks like this:
jQuery.get(url, [data], [callback(data, textStatus, XMLHttpRequest)], [dataType])
And the check looks like:
if ( jQuery.isFunction( data ) ) {
type = type || callback;
callback = data;
data = null;
}
jQuery.isFuncton()
is just a repeatedly used shortcut for jQuery.type(obj) === "function"
which is really using Object.toString()
, but this used to be done with typeof()
directly.
You can see the full source from jQuery 1.4.4 here.
How about just opening the file containing the culprit code?
My guess is that it's either doing type-checking on the variables (using typeof or such), or it's using arguments.length to determine how many arguments were passed, and using that to choose from a list of predefined allowed parameters.
JavaScript does not support method overloading through the use of different method signatures.
You can, in fact, pass 0 arguments to methods that list one or more, or pass more arguments than are listed.
All arguments passed to a method can be accessible through the keyword 'arguments' which behaves like an array.
That being said, you can then check for the presence of arguments directly or via the 'arguments' array.
function ABC(arg1, arg2, arg3){
if(typeof(arg2) === 'undefined') { }
if(typeof(arg3) === 'function'){ }
// arguments[0] == arg1, etc
}
ABC(1) ; // arg2 and arg3 are undefined
ABC(1,2,3,4); // arg1, arg2, and arg3 are defined, plus arguments[3] === 4
Knowing the above, you can therefore figure out how many arguments were provided, and use typeof() calls to determine what type.
In JavaScript, the argument list in a function definition doesn't force you to call the function with exactly those arguments:
// Given this definition....
function foo(one, two){
}
// ... all these calls are valid:
foo();
foo(1);
foo(1, 2);
foo(1, 2, 3);
And, of course, JavaScript is loosely typed as well:
foo(1, 2);
foo("Hello", "World");
foo(new Date, {foo: "bar"});
Using these two concepts, the language allows you to overload methods to your will:
function foo(){
var info = "Argument list:\n";
for(var i=0, len=arguments.length; i<len; i++){
info += "- Argument #" + (i+1) + " is a " + typeof(arguments[i]) + "\n";
}
alert(info);
}
foo(1, "1", {}, [], function(){});
Gives:
Argument list:
- Argument #1 is a number
- Argument #2 is a string
- Argument #3 is a object
- Argument #4 is a object
- Argument #5 is a function
+1 for Jani's answer. Just check the type of each parameter, and adjust your logic accordingly.
精彩评论