在JavaScript中,Lua的省略号相当于什么?

时间:2014-01-01 19:00:16

标签: javascript syntax parameters optional-parameters ellipsis

在Lua中,这样的函数是有效的:

function FuncCallHack(Func, ...)
    return Func(...)
end

我有可能在JavaScript中执行此操作吗?对于那些不熟悉Lua的人来说,...意味着“未分组数组形式的所有无索引参数”。我在JavaScript中尝试了...,它似乎没有功能,而且由于谷歌不喜欢搜索特殊字符,所以它没有多大帮助。

4 个答案:

答案 0 :(得分:6)

JavaScript具有arguments伪数组和apply函数;你可以这样做:

function FuncCallHack(Func) {
    return Func.apply(this, [].slice.call(arguments, 1));
}

这是如何工作的:

  1. arguments - 这是一个伪数组,包含调用代码传递给函数的所有参数(包括格式参数Func)。

  2. [].slice.call(arguments, 1)是一种获取除第一个参数之外的所有参数的数组的方法。 (这是一个常见的习惯用法。它的工作原理是将Array#slice方法应用于arguments伪数组,使用Function#call [与下面的Function#apply非常相似,它只是接受传递不同的args]。)遗憾的是,arguments本身不一定有slice方法,因为它不是一个真正的数组。

  3. 然后我们使用Function#apply方法(所有JavaScript函数都使用它)使用与Func调用相同的this值来调用FuncCallHack },并将除Func之外的所有参数传递给它。

  4. 你也可以稍微不同地定义它:

    function FuncCallHack(Func, args) {
        return Func.apply(this, args);
    }
    

    ......这仍然很容易使用:

    FuncCallHack(SomeFunction, [1, 2, 3]);
    // Note this is an array --^-------^
    

答案 1 :(得分:3)

Javascript尚不支持此功能。

相反,您可以循环遍历arguments类似数组的对象以查看每个参数。

要获取前两个参数之后的所有参数的数组(假设有两个命名参数),您可以编写

Array.prototype.slice.call(arguments, 2)

答案 2 :(得分:1)

ES6提供原生支持,它的名称为Rest parametersSpread operator

function FuncCallHack(Func, ...args) {
    return Func(...args)
}

Feature availability

答案 3 :(得分:0)

这可能无处不在,但在JavaScript中简洁地复制{...}是一个巧妙的技巧。

function varg(f, a) {
    f = f || varg.caller || arguments.caller;
    a = a || f.arguments;
    return Array.prototype.slice.call(a, f.length);
}

function f(a) {
    var b;
    // varg() could be used in one of the following ways:
    b = varg();  // Non-standard: uses caller.
    b = varg(f); // Not strict compliant: uses a function's arguments property.
    b = varg(f, arguments); // Should be safe to use everywhere.
    return b;
}

console.log(f(1));
console.log(f(1, 2));
console.log(f(1, 2, 3));

这里发生的是在varg()内,调用函数是从caller推断的,其参数是通过检查其arguments属性来确定的。然后将参数伪数组切割成一个实数数组,从f.length开始,表示 arity ,或者调用函数需要多少个参数,从而避免使用任何参数。硬编码的幻数。

但是,如果您尝试解决的问题只是将函数的参数重定向到另一个函数,那么T.J. Crowder's answer更合适。

function FuncCallHack(Func) {
  return Func.apply(this, [].slice.call(arguments, 1));
}