ホームページ > ウェブフロントエンド > jsチュートリアル > イベント ハンドラーをアタッチするときに、JavaScript ループが常にカウンター変数の最終値を出力するのはなぜですか?

イベント ハンドラーをアタッチするときに、JavaScript ループが常にカウンター変数の最終値を出力するのはなぜですか?

Linda Hamilton
リリース: 2024-12-28 05:40:15
オリジナル
844 人が閲覧しました

Why Does My JavaScript Loop Always Output the Final Value of the Counter Variable When Attaching 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); // WRONG: i will always be 5
    };
    document.body.appendChild(link);
  }
}
ログイン後にコピー

生成されたリンクのいずれかがクリックされると、アラートには常に「リンク 5」が表示されます。これは、var で定義された JavaScript の変数がブロック スコープではなく関数スコープであるためです。ループが終了すると、i は値 5 を保持し、すべての内部関数がそれを参照し、均一な出力が得られます。

修正された解決策は、クロージャ内で i の値をキャプチャすることにあります。次のスニペットを考えてみましょう:

function addLinks() {
  for (var i = 0, link; i < 5; i++) {
    link = document.createElement("a");
    link.innerHTML = "Link " + i;
    link.onclick = function (num) { // Closure around i
      return function () {
        alert(num); // num retains its original value
      };
    }(i); // Execute the outer function immediately to capture i
    document.body.appendChild(link);
  }
}
ログイン後にコピー

この場合、num は各反復の i の現在の値にバインドされます。内部関数が実行されると、num はループ実行時の i の値に一貫して設定されます。

さらに、データの保存に DOM ノードを利用する効率的な代替手段が存在します。

function linkListener() {
  alert(this.i);
}

function addLinks() {
  for (var i = 0; i < 5; ++i) {
    var link = document.createElement('a');
    link.appendChild(document.createTextNode('Link ' + i));
    link.i = i;
    link.onclick = linkListener;
    document.body.appendChild(link);
  }
}
ログイン後にコピー

DOM 要素自体に情報を付加することで、追加の関数オブジェクトの必要性が回避され、効率が向上します。

以上がイベント ハンドラーをアタッチするときに、JavaScript ループが常にカウンター変数の最終値を出力するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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