8

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

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

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

proxy(1,2,3,4);

基本上,我们知道 apply 需要一个数组作为第二个参数,但我们也知道这arguments不是一个正确的数组。代码按预期工作,所以可以肯定地说我可以将任何类似数组的对象作为第二个参数传递给apply()?

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

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

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

4

3 回答 3

7

根据MDNFunction.prototype.apply中的定义:

fun.apply(thisArg[, argsArray])

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

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

由于第二个参数apply接受“类似对象的数组,指定应调用函数的参数”。据我了解,这个类似数组的对象应该具有length内部迭代的属性,以及用于访问值的数字定义属性(零索引)。

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

于 2013-05-14T12:56:06.507 回答
3

假设 ECMAScript 5.1:是的。根据 ECMA-262, 10.6,arguments 对象具有15.3.4.3 ( ) 所需的length和 index 属性。Function.prototype.apply

于 2013-05-14T13:01:37.663 回答
1

MDN 只能代表 Mozilla 实现。所有实现都应遵守的实际规范如下:

15.3.4.3   Function.prototype.apply (thisArg, argArray)

When the apply method is called on an object func with arguments thisArg and
argArray, the following steps are taken:

1.  If IsCallable(func) is false, then throw a TypeError exception.
2.  If argArray is null or undefined, then
      Return the result of calling the [[Call]] internal method of func,
      providing thisArg as the this value and an empty list of arguments.
3.  If Type(argArray) is not Object, then throw a TypeError exception.
4.  Let len be the result of calling the [[Get]] internal method of argArray
      with argument "length".
5.  If len is null or undefined, then throw a TypeError exception.
6.  Let n be ToUint32(len).
7.  If n is not equal to ToNumber(len), then throw a TypeError exception.
8.  Let argList be an empty List.
9.  Let index be 0.
10. Repeat while index < n
      a. Let indexName be ToString(index).
      b. Let nextArg be the result of calling the [[Get]] internal method of
         argArray with indexName as the argument.
      c. Append nextArg as the last element of argList.
      d. Set index to index + 1.
11. Return the result of calling the [[Call]] internal method of func,
      providing thisArg as the this value and argList as the list of arguments.

The length property of the apply method is 2.

NOTE The thisArg value is passed without modification as the this value. This
     is a change from Edition 3, where an undefined or null thisArg is replaced
     with the global object and ToObject is applied to all other values and that
     result is passed as the this value.

似乎属性length和数字索引值是唯一的先决条件。

于 2013-05-14T13:08:41.547 回答