ループ内のクロージャによりすべてのリンクが同じ値を表示するのはなぜですか?

Mary-Kate Olsen
リリース: 2024-10-27 21:41:30
オリジナル
1100 人が閲覧しました

 Why Do Closures in Loops Make All Links Display the Same Value?

ループ内の JavaScript クロージャ: わかりやすく解説

クロージャを理解する

JavaScript のクロージャを使用すると、関数が直接の外部から変数にアクセスできるようになりますスコープ、プライベート データ コンテキストの作成。ただし、クロージャによって参照される変数は、外側の関数の実行が終了した後でもアクセス可能なままです。

ループ内のクロージャの問題

次のコード スニペットを考えてみましょう:

<code class="javascript">for (var i = 0; i < 5; i++) {
  link = document.createElement("a");
  link.innerHTML = "Link " + i;
  link.onclick = function (num) {
    return function () {
      alert(num);
    };
  }(i);
  document.body.appendChild(link);
}</code>
ログイン後にコピー

この例では、内部関数に num として渡された i の値が、すべてのリンク要素にわたって「共有変数」を作成するクロージャによってキャプチャされます。これは、リンクをクリックすると常に i の最後の値 (この場合は 4) が表示されることを意味します。

関数ファクトリとして IIFE (即時に呼び出される関数式) を使用する

この問題を解決するには、リンクごとに IIFE を作成し、i の値を引数として渡します。

<code class="javascript">function addLinks() {
  for (var i = 0; i < 5; i++) {
    link = document.createElement("a");
    link.innerHTML = "Link " + i;

    // IIFE used as a function factory
    link.onclick = (function (num) {
      return function () {
        alert(num);
      };
    })(i);
    document.body.appendChild(link);
  }
}</code>
ログイン後にコピー

このバージョンでは、各 IIFE は i の値が固定された独立したスコープを作成します。関数の作成時刻。これにより、クリックされた順序に関係なく、各リンク要素が i の独自のプライベート コピーを持つことが保証されます。

代替アプローチ: 関数ジェネレーター

別のオプションは次のとおりです。関数ジェネレーターを使用して i の現在値を参照する関数を作成するには:

<code class="javascript">function generateMyHandler(x) {
  return function () {
    alert(x);
  };
}

for (var i = 0; i < 5; i++) {
  link = document.createElement("a");
  link.innerHTML = "Link " + i;
  link.onclick = generateMyHandler(i);
  document.body.appendChild(link);
}</code>
ログイン後にコピー

この場合、generateMyHandler 関数は、次の時点で i の特定の値にバインドされた新しい関数を返します。関数呼び出し。

JavaScript クロージャーが変数をキャプチャする方法を理解し、適切な手法を使用して分離されたスコープを作成することで、開発者は共有変数を含む複雑なループ シナリオを効果的に処理できます。

以上がループ内のクロージャによりすべてのリンクが同じ値を表示するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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