質問

から: http://ejohn.org/apps/learn/#2

Function.prototype.bind = function(){
  var fn = this, args = Array.prototype.slice.call(arguments), object = args.shift();
  return function(){
    return fn.apply(object,
      args.concat(Array.prototype.slice.call(arguments)));
  };
};

2回目のリターンが必要な理由(fn.applyの前)を教えてもらえますか?

また、誰もがなぜargs.concatが必要なのかを説明できますか?なぜそれは書き直さないのでしょうか:

fn.apply(object, args)

それ以外の

return fn.apply(object,
          args.concat(Array.prototype.slice.call(arguments)));
役に立ちましたか?

解決

それ以外の場合は、バインドされた関数からの返品値が失われるため、2番目のリターンが必要です。

あなたはすでにこれを知っているかもしれませんが、言うまでもなく害はありません。ラップしない場合 fn.apply 別の関数の中で、私たちは関数を直接呼び出しています fn これは、次の最適です bind 実行コンテキストを設定することになっているだけです(何がすべきか this 関数内を参照してください)、それを呼び出しません。

JavaScriptメソッドは、電話をかけることで呼び出すことができます call また apply それらの方法。ここに小さな例があります:

function example() {
    alert("useless example");
}

example.apply() // or example.call(), alerts "useless example";

プロトタイプのbind()の外部関数は、バインドされた関数の周りの目に見えないラッパーのように機能するはずです。したがって、ラッパーに渡される引数もバインドされた関数に渡される必要があり、バインドされた関数が返す値を返す必要があります。そのため、returnステートメントがあります。

fn.apply内でargs.concatを実行する理由は異なり、オプションではありません。 bind プロトタイプでは、バインドされた関数に引数を準備できます。

args 私たちが呼んだときに渡された議論を表します bind 関数について。 arguments 結合関数と呼ばれるときに渡された引数を表します。基本的に2つの配列を連結しています。

上記の例から:

var obj = { x: 'prop x' };
var boundExample = example.bind(obj, 12, 23); // args => 12, 23
boundExample(36, 49); // arguments => 36, 49

// arguments that our example() function receives => 12, 23, 36, 49

他のヒント

古い投稿ですが、新しいアプローチ;)

Function.prototype.bind = function(){
    var fn = this, 
    context = arguments[0], 
    args = Array.prototype.slice.call(arguments, 1);
    return function(){
        return fn.apply(context, args.concat([].slice.call(arguments)));
    }
}

obj = {'abc':'x'};
var func = function() {
  console.log(arguments);
  alert(this.abc);
}
var x = func.bind(obj);

console.log(x(1,2,3));

これは説明するのに非常に良い例です。実行して、コンソールログを確認します。次に、コードを変更して除外します

[].slice.call(arguments)

X(1,2,3)の実行のコンソール。ログがもう引数を表示していないことがわかります。 これは、引数オブジェクトがすべての関数内のローカル変数であるためです。 それは少し混乱するかもしれませんが、それが意味するのは基本的に:

var x = func.bind(obj,1,2,3);

この関数を内部的に返します:

function() {
    return fn.apply(obj, [1,2,3].concat([].slice.call(arguments)));
}

したがって、それは関数のテンプレートのようなものです。

あなたが今それを実行するとき:

x(4,5,6)

これは実行されます:

fn.apply(obj, [1,2,3].concat([].slice.call(arguments)))

特別な引数を使用してobject = {0:4,1:5,2:6}。[] .slice.callを使用して配列に変換できます。関数。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top