8

jsGarden でこのコードに出くわしましたが、連結する意味がわかりませcallapply。どちらも特定のコンテキスト オブジェクトで関数を実行しますが、なぜ連鎖できるのでしょうか?

function Foo() {}

Foo.prototype.method = function(a, b, c) {
    console.log(this, a, b, c);
};

// Create an unbound version of "method" 
// It takes the parameters: this, arg1, arg2...argN
Foo.method = function() {

    // Result: Foo.prototype.method.call(this, arg1, arg2... argN)
    Function.call.apply(Foo.prototype.method, arguments);
};
4

4 に答える 4

12

callvia を呼び出していapplyます。つまりcall、関数 (「メソッド」) をapply呼び出すために使用し、(ほぼ) 配列の形式で引数を取得しているため、呼び出しを行うために使用しています。

それを分解するには:

Function.call

call()これは、Function プロトタイプから継承された、すべての Function インスタンスで使用可能な関数への参照です。

Function.call.apply

callこれは、関数への参照を介した への参照applyです。はオブジェクトapply経由で参照されるため、 への呼び出しが行われると、値は関数への参照になります。callapplythiscall

Function.call.apply(Foo.prototype.method, arguments);

したがって、 をcall介して関数を呼び出し、を値としてapply渡し、引数として "Foo.mmethod" に引数を渡します。Foo.prototype.methodthis

基本的にはこれと同じ効果だと思います:

Foo.method = function() {
  var obj = arguments[0], args = [].slice.call(arguments, 1);
  Foo.prototype.method.apply(obj, args);
}

しかし、確認するために試してみる必要があります。はい、そうです。apply()したがって、そのトリックの要点は、目的のthis値がパラメーターを保持する配列の最初の要素である場合に呼び出す方法であると要約できます。言い換えれば、通常、呼び出すapply()と、必要なthisオブジェクト参照が取得され、パラメーター (配列内) が取得されます。ただし、ここでは、目的thisのパラメーターをパラメーターとして渡すという考え方であるため、呼び出しを行うには、それを分離する必要がありますapply。個人的には、私の「翻訳」のようにします。なぜなら、(私にとって)少し頭が曲がらないからです。しかし、慣れると思います。私の経験では、一般的な状況ではありません。

于 2012-07-26T16:50:26.820 に答える
2

コードは次のようにする必要があると思います。

function Foo() {}

Foo.prototype.method = function(a, b, c) {
 console.log(this, a, b, c);
};

Foo.method = function() {

 //Notice this line:
 Function.apply.call(Foo.prototype.method, this, arguments);
};

それから

Foo.method(1,2,3) => function Foo() {} 1 2 3

その他の例:

Function.apply.call(Array,this,[1,2]) => [1, 2]
Function.call.apply(Array,this,[1,2]) => [window]
Function.call.call(Array,this,[1,2])  => [[1, 2]]
于 2015-03-02T12:29:14.323 に答える
1

applyは、2 番目の引数として配列を取り、call単一のパラメーターを取ります。

 // lets take call,
 var callfn = Function.prototype.call;
 // an ordinary function from elsewhere
 var method = Foo.prototype.method;
 // and apply the arguments object on it:
 callfn.apply(method, arguments);

したがって、最初のarguments項目は のthis値にmethodなり、後続の項目は単一のパラメーターを埋めます。

結果は、インスタンス (または類似のもの) を最初の引数として取り、それにプロトタイプを適用するmethodFooコンストラクターの静的関数です。考えられるユースケースは、通常は としてのみ利用可能な関数を定義することでした。FoomethodObject.hasOwnPropertyObject.prototype.hasOwnProperty

最終的に、methoda) 継承しないか、b) 上書きするオブジェクトに適用する必要がある場合、1 つの「プロトタイプ」と 1 つの「呼び出し」の呼び出しが短くなります。

于 2012-07-26T16:53:14.503 に答える