ループ内の JavaScript クロージャ: 問題とその解決策を理解する
問題は、var キーワードを使用した変数宣言を持つループ内でクロージャを使用するときに発生します。 。クロージャは、関数が終了した後でも、変数を含むクロージャが定義されている環境をキャプチャし、それらへの参照を作成します。これにより、ループの実行中にキャプチャされた変数の値が変更されると、予期しない動作が発生する可能性があります。
問題:
次のコードを考えてみましょう:
<code>for (var i = 0; i < 3; i++) { funcs[i] = function() { console.log("My value:", i); }; }</code>
このコードは 3 回繰り返すループを作成します。各反復内で関数が定義され、配列に格納されます。期待される出力は次のようになります:
<code>My value: 0 My value: 1 My value: 2</code>
ただし、実際の出力は次のようになります:
<code>My value: 3 My value: 3 My value: 3</code>
これは、変数 i がクロージャによってキャプチャされ、最終的な値に更新されるためです。クロージャが実行される前に値 3 が設定されます。
ES6 解決策: 'let' キーワードの使用
ECMAScript 6 (ES6) では、ブロックを作成する let キーワードが導入されています。 -スコープ変数。この例では、var の代わりに let を使用して、反復ごとに新しい変数 i を作成できます。
<code>for (let i = 0; i < 3; i++) { funcs[i] = function() { console.log("My value:", i); }; }</code>
今回は、各クロージャが独自の個別の i 変数をキャプチャし、期待される出力が取得されます。 .
ES5.1 解決策: 'forEach' を使用する
JavaScript の Array.prototype.forEach メソッドは、配列を反復処理するクリーンな方法を提供します。 forEach に渡される各コールバック関数は、現在の要素の周囲に個別のクロージャを取得します。
<code>var someArray = [ /* whatever */ ]; someArray.forEach(function(element) { // Code specific to this element });</code>
古典的な解決策: クロージャの使用
クロージャを使用して変数をバインドできます。関数外の特定の値:
<code>function createfunc(i) { return function() { console.log("My value:", i); }; } var funcs = []; for (var i = 0; i < 3; i++) { funcs[i] = createfunc(i); }</code>
ここでは、createfunc を使用して i 固有のクロージャが作成され、funcs 配列に格納されます。これらの各クロージャが実行されると、対応する i 変数が参照され、正しい出力が得られます。
以上がJavaScript ループのクロージャ変数参照に関する問題を解決するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。