ホームページ ウェブフロントエンド jsチュートリアル イベント ハンドラーをバインドするときに JavaScript ループによって予期しない動作が発生するのはなぜですか?

イベント ハンドラーをバインドするときに JavaScript ループによって予期しない動作が発生するのはなぜですか?

Dec 24, 2024 pm 08:40 PM

Why Do JavaScript Loops Create Unexpected Behavior When Binding Event Handlers?

悪名高い 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 サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットな記事タグ

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

JavaScriptの文字列文字を交換します JavaScriptの文字列文字を交換します Mar 11, 2025 am 12:07 AM

JavaScriptの文字列文字を交換します

jQueryは要素のパディング/マージンを取得します jQueryは要素のパディング/マージンを取得します Mar 01, 2025 am 08:53 AM

jQueryは要素のパディング/マージンを取得します

jQuery日付が有効かどうかを確認します jQuery日付が有効かどうかを確認します Mar 01, 2025 am 08:51 AM

jQuery日付が有効かどうかを確認します

10 jQuery Accordionsタブ 10 jQuery Accordionsタブ Mar 01, 2025 am 01:34 AM

10 jQuery Accordionsタブ

10 jqueryプラグインをチェックする価値があります 10 jqueryプラグインをチェックする価値があります Mar 01, 2025 am 01:29 AM

10 jqueryプラグインをチェックする価値があります

カスタムGoogle検索APIセットアップチュートリアル カスタムGoogle検索APIセットアップチュートリアル Mar 04, 2025 am 01:06 AM

カスタムGoogle検索APIセットアップチュートリアル

ノードとHTTPコンソールを使用したHTTPデバッグ ノードとHTTPコンソールを使用したHTTPデバッグ Mar 01, 2025 am 01:37 AM

ノードとHTTPコンソールを使用したHTTPデバッグ

jQueryはscrollbarをdivに追加します jQueryはscrollbarをdivに追加します Mar 01, 2025 am 01:30 AM

jQueryはscrollbarをdivに追加します

See all articles