8

次のコードがあるとします(まったく役に立たないことはわかっています)

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

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

proxy(1,2,3,4);

基本的に、apply が 2 番目のパラメーターとして配列を想定していることはわかっていますが、それがarguments適切な配列ではないこともわかっています。コードは期待どおりに動作するので、任意の配列のようなオブジェクトを の 2 番目のパラメーターとして渡すことができると言っても過言ではありapply()ませんか?

以下も動作します (少なくとも Chrome では):

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

更新: IE<9 で 2 番目のコード ブロックが失敗するようですが、最初のコード ブロック ( を渡す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

2 番目の引数として、「関数を呼び出す引数を指定するオブジェクトのような配列」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 オブジェクトには、length15.3.4.3 ( Function.prototype.apply) が必要とする および index プロパティがあります。

于 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 に答える