プログラミングにおいて、クロージャは外部スコープから変数をキャプチャする際に重要な役割を果たします。ただし、ループ内で使用すると、クロージャ汚染として知られる予期しない結果が生じる可能性があります。この記事では、この問題を調査し、それを解決するための実用的な解決策を提供します。
次のコードを考えてみましょう:
<code class="javascript">var funcs = []; for (var i = 0; i < 3; i++) { funcs[i] = function() { console.log("My value:", i); }; } for (var j = 0; j < 3; j++) { funcs[j](); }</code>
残念ながら、このコードの出力は次のとおりです:
<code>My value: 3 My value: 3 My value: 3</code>
ではなく:
<code>My value: 0 My value: 1 My value: 2</code>
この問題は、ループ内で宣言された各関数が外側のスコープから同じ i
変数をキャプチャするために発生します。 2 番目のループ内で関数が呼び出されると、関数はすべて同じ i
を参照します。この
let
ES6 の解決策: let
ES6 では、ブロック スコープの変数を作成する let
キーワードが導入されました。ループ内で i
を使用すると、各反復が独自の
<code class="javascript">for (let i = 0; i < 3; i++) { funcs[i] = function() { console.log("My value:", i); }; }</code>
forEach
ES5.1 解決策: forEach
別の配列の解決策は、
<code class="javascript">var someArray = [/* values */]; someArray.forEach(function(element) { // ...code specific to this element... });</code>
forEach
<code class="javascript">var funcs = []; function createFunc(i) { return function() { console.log("My value:", i); }; } for (var i = 0; i < 3; i++) { funcs[i] = createFunc(i); } for (var j = 0; j < 3; j++) { funcs[j](); }</code>
i
以上がループ内の閉鎖汚染を克服する方法: 実践ガイドの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。