3

重複の可能性:
呼び出しを連鎖させて一緒に適用することの意味は何ですか?

私はこのようないくつかのコードを見つけました:

function fun() {
    return Function.prototype.call.apply(Array.prototype.slice, arguments);
}

私はcallapplyjsを知っていますが、それらが一緒になると混乱します。

それなら私は疑問に思います

Function.prototype.call.apply(Array.prototype.slice, arguments)

と同じです:

Array.prototype.slice.apply(arguments);

そうでない場合、最初の行は何をしますか?

4

2 に答える 2

11

よし、置換によってこの問題に取り組みましょう。まず始めに:

Function.prototype.call.apply(Array.prototype.slice, arguments);

私たちが知っていること:

  1. Function.prototype.call関数です。
  2. thisポインターは をcall指しFunction.prototypeます。
  3. のポインターをにapply変更するために使用します。thiscallArray.prototype.slice
  4. arguments適用されます (パラメータとして渡されません) call

したがって、上記のステートメントは次と同等です。

Array.prototype.slice.call(arguments[0], arguments[1], ...);

このことから、次のことがわかります。

  1. Array.prototype.slice関数です。
  2. thisポインターは をslice指しArray.prototypeます。
  3. のポインターをにcall変更するために使用します。thisslicearguments[0]
  4. arguments[1], ...にパラメータとして渡されますslice

これは次と同じです。

arguments[0].slice(arguments[1], ...);

これの利点は、1 行で高速なバインドされていないラッパーを作成できることです。slice

編集:バインドされていない高速ラッパーを作成するより良い方法は次のとおりです (一部の古いブラウザーでは機能しない可能性があることに注意してください。ただし、今はそれについて心配する必要はありません。サポートbind):

var slice = Function.prototype.call.bind(Array.prototype.slice);

これは次と同じです。

function slice() {
    return Function.prototype.call.apply(Array.prototype.slice, arguments);
}

使い方:

  1. Function.prototype.call関数です。
  2. thisポインターは をcall指しFunction.prototypeます。
  3. のポインターをにbind変更するために使用します。thiscallArray.prototype.slice
  4. bindarguments適用される関数を返しますcall

おまけ:あなたのプログラミング スタイルが私のように非常に機能的である場合、コードの一部が非常に便利であることがわかります。

var funct = Function.prototype;
var obj = Object.prototype;
var arr = Array.prototype;

var bind = funct.bind;

var unbind = bind.bind(bind);
var call = unbind(funct.call);
var apply = unbind(funct.apply);

var classOf = call(obj.toString);
var ownPropertyOf = call(obj.hasOwnProperty);
var concatenate = call(arr.concat);
var arrayFrom = call(arr.slice);
  1. callこれを使用すると、またはを使用してバインドされていないラッパーを簡単に作成できますapply
  2. classOf値の内部を取得するために使用でき[[Class]]ます。
  3. ownPropertyOf内部 for in ループを使用できます。
  4. concatenate配列を結合するために使用できます。
  5. arrayFrom配列の作成に使用できます。
于 2012-10-22T03:01:36.417 に答える
1

次の行で、.apply.callメソッドであるという呼び出しコンテキストでメソッドを.call呼び出し.sliceargumentsコレクションは個別の引数として渡されます。

Function.prototype.call.apply(Array.prototype.slice, arguments);

これは効果的に私たちにこれを与えます:

Array.prototype.slice.call(arguments[0], arguments[1], arguments[2] /*, etc */);

これは.slice()、オブジェクトの最初の項目をarguments呼び出し元のコンテキストとして、残りの引数を通常の引数として呼び出されることを意味します。

したがって、の内容argumentsが次のようなものである場合:

myarray, 0, 5

あなたは事実上これで終わります:

myarray.slice(0, 5)

これは基本的にこれを行う必要がない方法です:

var arr = arguments[0];
var rest = Array.prototype.slice(arguments, 1);

var result = arr.slice.apply(arr, rest);
于 2012-10-22T02:45:09.320 に答える