私は、javascriptのbind()がどのように機能するかについての考えを整理しようとしています。
もしそうなら
var f = function (a) { ... }
var g = f.bind(obj);
g(1)
その後、fはobj
をthis
として、1
をa
として呼び出します。
私が考えたのは、gがfのラッパー関数だということです。
しかし、私がするとき
var f = function (a) { ... }
var g = f.bind(obj);
g.call(1)
その後、fはthis
およびa
undefinedとして1
で呼び出されます。
したがって、gは単なるラッパーではなく、call
が通常の関数とバインドされた関数を何らかの形で区別しているようです。
もう1つは、関数を部分的にこれ以上適用できないことです。
var f = function (a) { ... }
var g = f.bind(obj);
var h = g.bind(1);
h();
次に、obj
およびthis
undefinedとしてa
でfが呼び出されます。
この動作の原因は何ですか?
編集
この質問の構造は実際には間違っています。どのように見えるべきかについての受け入れられた答えを参照してください(一般的に、call
とbind
が常に最初の引数としてコンテキスト引数を必要とすることに気づいていません)。
bind
を使用してオブジェクトを関数にバインドすると、オーバーライドできません。 MDNドキュメンテーション でわかるように、仕様に明確に記述されています。
」bind()関数は、呼び出される関数(バインドされた関数のターゲット関数)と同じ関数本体(ECMAScript 5用語の内部呼び出しプロパティ)で新しい関数(バインドされた関数)を作成します)この値をbind()の最初の引数にバインドし、オーバーライドできません。 "
つまり、次の場合も同様です。
g.call(1);
仕様に従っているブラウザでは、1
ではなくobj
としてthis
を取得します。
もちろん、複数の引数をバインドできます:
var sum = function(a, b, c) { return a + b + c };
var sumAB = sum.bind(null, 1, 5);
var sumC = sumAB.bind(null, 2);
console.log(sumC());
ただし、上書きできないため、コンテキストオブジェクトは常に最初のbind
で指定されたものになります。
混乱を避けるために、 call の最初の引数はコンテキストオブジェクト(this
)であり、残りの引数があります。
その意味は:
var obj = { foo: function(bar) { console.log(bar) } };
obj.foo('hello');
// equivalent to:
var foo = obj.foo;
foo.call(obj, 'hello');
それが役に立てば幸い。
引数を渡したことはありません。コンテキストを設定するだけです。 call
の最初の引数はコンテキスト(this
)として受け取られ、引数2以降は呼び出された関数の引数1以降として受け取られます。一方、bind
は新しいコンテキストで新しい関数を作成します—引数は呼び出されたときに渡されます。
最初のコードブロックから1
を関数f
の引数a
として渡す方法は次のとおりです。
f( 1 );
g( 1 );
g.call( this, 1 );
g.apply( this, [ 1 ] );