将'arguments'传递给'apply()'是否安全?

Dav*_*oli 8 javascript

假设我有以下代码(完全没用,我知道)

function add( a, b, c, d ) {
  alert(a+b+c+d);
}

function proxy() {
    add.apply(window, arguments);
}

proxy(1,2,3,4);
Run Code Online (Sandbox Code Playgroud)

基本上,我们知道apply需要一个数组作为第二个参数,但我们也知道这arguments不是一个合适的数组.代码按预期工作,所以可以安全地说我可以传递任何类似数组的对象作为第二个参数apply()吗?

以下内容也适用(至少在Chrome中):

function proxy() {
  add.apply(window, {
    0: arguments[0],
    1: arguments[1],
    2: arguments[2],
    3: arguments[3],
    length: 4
  });
}
Run Code Online (Sandbox Code Playgroud)

更新:似乎我的第二个代码块在IE <9中失败而第一个(传递arguments)工作.错误是Array or arguments object expected,因此我们将得出结论,传递总是安全的arguments,而在oldIE中传递类似数组的对象是不安全的.

Vis*_*ioN 7

从定义Function.prototype.applyMDN:

fun.apply(thisArg[, argsArray])

您还可以使用argumentsargsArray参数.arguments是函数的局部变量.它可以用于被调用对象的所有未指定的参数.因此,在使用该apply方法时,您不必知道被调用对象的参数.您可以使用arguments将所有参数传递给被调用对象.然后被调用对象负责处理参数.

参考: https ://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/apply

因为第二个参数apply接受"像对象一样的数组,指定应该调用函数的参数".据我所知,这个类似数组的对象应具有length内部迭代的属性,以及用于访问值的数字定义属性(零索引).

正如@Pointy所指出的那样,我的规范也证实了这一点:http://www.ecma-international.org/ecma-262/5.1/#sec-15.3.4.3.

  • 另外[规范的第15.3.4.3节](http://www.ecma-international.org/ecma-262/5.1/#sec-15.3.4.3)明确指出`apply`只关注值`length`和编号(索引)属性. (2认同)

Mat*_*ard 3

假设 ECMAScript 5.1:是的。根据 ECMA-262, 10.6,arguments 对象具有length15.3.4.3 ( Function.prototype.apply) 要求的 和 index 属性。

  • 哦,IE 明确表示:“期望数组或参数对象”,所以我想传递“参数”是安全的,传递类似数组的对象是不安全的 (2认同)