in my project, I register different functions (having different number of arguments) as listeners to a number of events. When the event takes place, I need to fire the associated function. I receive the parameters to be passed to listener method in the form of an array whereas the listener function expect each separate argument. So, I am doing it like this but I do not like the approach and would like to know if there is an elegant way of doing it,
function callListenerWithArgs(func, args){
switch(args.length){
case 1:
func(args[0]);
break;
case 2:
func(args[0], args[1]);
break;
case 3:
func(args[0], args[1], args[2])开发者_JAVA技巧;
break;
case 4:
func(args[0], args[1], args[2], args[3]);
break;
default:
func();
}
}
Use .apply
func.apply(null, args)
If you need to bind to a specific scope, you can pass another argument in to use as this
inside the function:
func.apply(scope, args);
Also, a nuance of JavaScript is that you can call functions with undefined values. So making a small tweak to your existing code will work in 95% of all cases (this isn't suggested as a solution, just pointing it out):
// will handle any number of args up to 7
function callListenerWithArgs(func, args){
func(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
}
If your func
is defined as:
function foo(a, b, c){
}
you get a
, b
, c
passed in, along with some more undefined
values that get ignored. As I said above, this works in 95% of cases. It doesn't work if you ever check arguments.length
in the called function since it will always be the same, regardless of the number of parameters the function defines.
Try this using function.apply
function callListenerWithArgs(func, args){
func.apply(window, args);
}
functionName.apply(thisScope, arguments)
would be more elegant. The arguments
argument must be an array.
You can build the Array like:
var args = [];
switch (arguments.length - 1) {
case 0:
break;
case 1:
args.push(arguments[1]);
break;
case 2:
args.push(arguments[1], arguments[2]);
break;
case 3:
args.push(arguments[1], arguments[2], arguments[3]);
break;
default:
args = Array.prototype.slice.call(arguments, 1);
}
or if the array is already built, just pass it as the second argument to .apply
func.apply(this, args);
See here.
You can get the number of arguments of a function:
var f = function ( ) { console.log(arguments.length); }
f( 2, 3 ) // > 2
That lets you implement your func
function directly in place.
function func() {
var nbArgs = arguments.length;
// ...
}
精彩评论