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

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

Linda Hamilton
リリース: 2024-12-24 20:40:13
オリジナル
788 人が閲覧しました

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

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート