ホームページ > ウェブフロントエンド > jsチュートリアル > JavaScript ループ内のイベント ハンドラーが同じ変数を参照するのはなぜですか?

JavaScript ループ内のイベント ハンドラーが同じ変数を参照するのはなぜですか?

DDD
リリース: 2024-11-05 20:36:02
オリジナル
713 人が閲覧しました

Why Do Event Handlers in JavaScript Loops Refer to the Same Variables?

JavaScript ループでのイベント ハンドラーの使用: 個別のイベント処理にクロージャを使用する

JavaScript では、HTML コードを使用するときにイベント ハンドラーが再生されます。ユーザーが Web ページと対話できるようにする上で重要な役割を果たします。ただし、これらのイベント ハンドラーがループ内で定義されている場合に共通の課題が発生し、予期しない動作が発生します。

この問題を説明するには、次のコード スニペットを考えてみましょう。

<code class="javascript">var blah = xmlres.getElementsByTagName('blah');
for(var i = 0; i < blah.length; i++) {
    var td = document.createElement('td');
    var select = document.createElement('select');
    select.setAttribute("...", "...");
    select.onchange = function() {
        onStatusChanged(select, callid, anotherid);
    };
    td.appendChild(select);
}
ログイン後にコピー

When an onchange 要素に関係なく、同じ値が onStatusChanged() メソッドに渡されることを示唆しています。イベントをトリガーした要素。この動作は、イベント ハンドラーを定義するときに JavaScript がクロージャを実装する方法に由来します。

具体的には、ループ内で、クロージャ select.onchange = function() は、変数 callid と anotherid を参照します。これらの変数は、実行中に割り当てられた値を保持します。ループの最後の反復。したがって、イベントがトリガーされると、これらの変数の値は、特定の

この問題に対処するには、イベント ハンドラーの定義時に select、callid、anotherid の値をキャプチャするクロージャを実装できます。次のコードは、このアプローチを示しています。

<code class="javascript">var blah = xmlres.getElementsByTagName('blah');
for(var i = 0; i < blah.length; i++) {
    var td = document.createElement('td');
    var select = document.createElement('select');
    select.setAttribute("...", "...");
    select.onchange = function(s,c,a)
    {
        return function()
        {
            onStatusChanged(s,c,a);
        }
    }(select, callid, anotherid);
    td.appendChild(select);
}</code>
ログイン後にコピー

要約すると、JavaScript ループ内でイベント ハンドラーを定義するときにクロージャーを使用することは、イベント ハンドラー関数が関連する変数の適切な値を確実に受け取るために不可欠です。これにより、特定の