悪名高い JavaScript ループの問題を理解する
JavaScript では、ループを使用して要素を生成し、それらをイベント ハンドラーにバインドするときに一般的な問題が発生します。 。次のコードは、この問題の例を示しています。
function addLinks() { for (var i=0, link; i<5; i++) { link = document.createElement("a"); link.innerHTML = "Link " + i; link.onclick = function () { alert(i); }; document.body.appendChild(link); } }
このコードは、クリックするとそれぞれ独自のインデックスを表示する 5 つのリンクを生成することを目的としています。ただし、クリックするとすべてのリンクに「リンク 5」が表示されます。この異常は、JavaScript のクロージャー メカニズムに起因します。
最初のスニペットでは、ループのイベント ハンドラー内で定義された内部関数が変数 i への参照を保持しています。ただし、ループの完了後、i の値は 5 とみなされます。その結果、イベント ハンドラーがalert(i) を呼び出すとき、i の値は常に 5 となり、誤った動作が発生します。
2 番目のコードスニペットでは、この問題は、すぐに呼び出される関数式 (IIFE) で内部関数を囲むことで解決されます。
link.onclick = function (num) { return function () { alert(num); }; }(i);
IIFE は、 inner 関数は反復ごとに作成されるため、目的の i 値がそのスコープ内に保持されます。イベント ハンドラーが実行されると、IIFE から取得した i の値を使用して正しいインデックスをアラートします。
あるいは、より効率的なアプローチは、i の現在の値を DOM ノードのプロパティに直接割り当てることです。イベント ハンドラーの実行中に簡単にアクセスできるようにします:
link.i = i; link.onclick = function () { alert(this.i); };
このソリューションにより、リンクごとに新しい関数オブジェクトを作成する必要がなくなります。
以上がイベント ハンドラーをバインドするときに JavaScript ループによって予期しない動作が発生するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。