Javascript未知数量的参数

时间:2011-06-22 15:24:20

标签: javascript variables arguments

在我的项目中,我注册了不同的函数(具有不同数量的参数)作为许多事件的监听器。当事件发生时,我需要触发相关的功能。我以数组的形式接收要传递给listener方法的参数,而listener函数期望每个单独的参数。所以,我这样做,但我不喜欢这种方法,并想知道是否有一种优雅的方式,

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]);
                break;
            case 4:
                func(args[0], args[1], args[2], args[3]);
                break;
            default:
                func();
        }
    }

5 个答案:

答案 0 :(得分:2)

使用.apply

func.apply(null, args)

如果需要绑定到特定范围,可以传入另一个参数以在函数内使用this

func.apply(scope, args);

此外,JavaScript的细微差别在于您可以使用未定义的值调用函数。因此,对现有代码进行小幅调整将在95%的情况下有效(这不是建议作为解决方案,只是指出来):

// 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]);
}

如果您的func定义为:

function foo(a, b, c){
}

您传入了abc以及一些被忽略的undefined值。正如我上面所说,这在95%的情况下起作用。如果您检查被调用函数中的arguments.length,它将无效,因为无论函数定义的参数数量是多少,它都将始终相同。

答案 1 :(得分:1)

使用function.apply

尝试此操作
function callListenerWithArgs(func, args){
    func.apply(window, args);
}

答案 2 :(得分:1)

functionName.apply(thisScope, arguments)会更优雅。 arguments参数必须是数组。

您可以像以下一样构建数组:

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);
}

或者如果数组已经构建,只需将其作为第二个参数传递给.apply

答案 3 :(得分:1)

func.apply(this, args);

请参阅here

答案 4 :(得分:-1)

您可以获取函数的参数数量:

var f = function ( ) { console.log(arguments.length); }
f( 2, 3 )  // > 2

这可让您直接实施func功能。

function func() {
  var nbArgs = arguments.length;
  // ...
}