2017-08-28 4 views
0

私はbind()関数を使っていましたが、私は現在認識していない状況に遭遇しました。 誰かが私に与えることができ、この例がこのように機能する理由を説明できますか? bind関数に渡されたインラインオブジェクトは、最初の繰り返しでのみ初期化され、参照が保持されているようです。 私はあなたが正しい方向に私を指すことができれば、私は.bind()の最初の引数は、コンテキストでJavascript Function.prototype.bind()インラインオブジェクト定義

class test { 

addLetter(element) { 
    console.log('addLetter', this.str); 
    this.str += element + ','; 
} 

foo() { 
    let arr = ['a', 'b', 'c', 'd', 'e', 'f', 'g']; 

    arr.forEach(this.addLetter.bind({ 
    str: '' 
    })); 
} 
} 

let a = new test(); 
a.foo(); 

OUTPUT: 
addLetter 
addLetter a, 
addLetter a,b, 
addLetter a,b,c, 
addLetter a,b,c,d, 
addLetter a,b,c,d,e, 
addLetter a,b,c,d,e,f, 
+0

「このキーワードはどのように機能しますか?」(https://stackoverflow.com/questions/3127429/how-does-the-this-keyword-work) – Erazihel

+1

あなたのコードは、 let cb = this.addLetter.bind({...}); arr.forEach(cb); ' - はい、バインドされたオブジェクトを1つだけ持つ*コールバックを作成しています。 – deceze

+0

確かに、私のエラーはforEachを通常のループとして考えていました、ありがとうございます。 –

答えて

1

引数を関数呼び出しから切り離した方が簡単です。以下のような関数呼び出し:

someFunc(<expression>); 

は同等です:

var tempVar = <expression>; 
someFunc(tempVar); 

だからあなたの場合には、それはこのようなものだ:

var tempVar = this.addLetter.bind({ 
    str: '' 
}); 
arr.forEach(tempVar); 

これは、我々が一度だけbind()を呼んでいるclearthatます、我々はtempVarと設定します。特定のオブジェクトにバインドされた関数を作成します。その後、forEachは、その機能を繰り返し呼び出す。関数が呼び出されるたびに再利用されますちょうど単一のオブジェクトがありますなぜ今、それは本当に明確にする必要があり

var tempObj = { str: '' }; 
var tempFun = this.addLetter.bind(tempObj); 
arr.forEach(tempFun); 

:我々は、さらにそれを打破することができます。

+0

ありがとう、本当に分かりやすいです。 –

1

:-) veeeery感謝するでしょう、これについてどのドキュメントを見つけることができませんでした。この場合、それはあなたがそれを参照し、内にそのstrプロパティを使用している、今

{ 
    str: '' 
} 

です。今、我々は.bind()が関数を返すことを知っています。その関数は.forEach()の中で呼び出されます。

このbind generated functionは、最初の引数として(繰り返しに応じて)要素を受け取ります。

最初の反復インデックスはゼロで、bind generated function関数は引数として 'a'を受け取ります。

声明

this.str += element + ','; 

'' + 'a'としてSTRを強化します。 2回目の反復では、引数は 'b'で、それは'a,' + 'b'などに追加されます。

あなたはあなたが見る結果を見ることができます。これがあなたの質問を明確にしてくれたら教えてください。

+0

なぜ 'bind'はすべての反復で同じ匿名オブジェクトを渡しますが、繰り返しごとにオブジェクトを作成しませんか? – Dmitry

+0

それは良い質問です。だから、拘束されているのは匿名オブジェクトへの参照です。ループでは 'str'プロパティだけを変更します。それぞれのループ反復で作成された新しいオブジェクトは存在しないため、同じオブジェクトの 'str'プロパティが(連結を介して)拡大し続けています。 – 82Tuskers

+0

@Dmitry 'bind'はループを認識していないためです。一度しか呼び出されないので、オブジェクトを一度バインドするだけです。 – deceze