0

Javascript を学習していて、これら 2 つの機能が異なる理由がわかりません。この例を見ました(関数に名前を追加しました):

var txt = ["a","b","c"];

for (var i = 0; i < 3; ++i ) {    
    setTimeout((function myBind(msg) { 
      return function myAlert() { alert(msg); } 
    })(txt[i]), 1000);        
}​

alert を呼び出す関数が返されていることがわかります。だから私は考えました、なぜそれを直接返さないのですか:

var txt = ["a","b","c"];

for (var i = 0; i < 3; ++i ) {    
    setTimeout( function() { alert(txt[i]);} ,1000);        
}​

これにより、「未定義」のアラートが発生します。1秒後にループが終了し、iが3に設定されたため、txt [3]にアクセスしようとしていることが原因であることは理解していますが、元のセットアップでこの問題をどのように回避したかはわかりません。

4

4 に答える 4

1

例 1

クロージャーはスクリプトを即座に実行し、その関数内に格納されたままのパラメーターを渡すこともできます。パラメータ==パラメータ

(function(param){})(parameter)

あなたの例では、関数は setTimeout によって実行される別の関数を返します。

(function(param){
 return function(){
  alert(param)
 }
})(parameter)

以前にパラメーターを関数に渡したので、正しい値が返されます。

例 2

setTimeout は非常に高速に 3 回呼び出されますが、パラメーターはどこにも保存されないため、txt と i からわかっている最後の値が取得され、setTimeout が実行される前にループが終了すると、値は 3 になります。


基本的に最初の例では、すべての txt[i] をこれらのクロージャーで作成した各関数内に格納します。

2番目のものでは、txt [i]をどこにも保存しません。setTimout 関数にアラート txt[i] を指示するだけです。これは 1 秒後に for ループによって作成された最後のものです。

于 2013-08-23T02:59:14.033 に答える
1

閉鎖について読む必要があります。この回答を参照してください JavaScript クロージャーはどのように機能しますか? それらを理解すること。

于 2013-08-23T02:47:23.143 に答える
0

最初のバージョンでは、txt[i]は新しい変数 にバインドされています。この変数は、作成さmsgれるそれぞれの場所が異なりますfunction

2 番目のバージョンでは、のスコープがさらに上にあるためi、 は各 の同じ場所です。ループのたびに新しい変数が作成されるわけではありません。functionii

于 2013-08-23T02:46:59.897 に答える