首頁  >  文章  >  web前端  >  為什麼循環中的閉包會使所有連結顯示相同的值?

為什麼循環中的閉包會使所有連結顯示相同的值?

Mary-Kate Olsen
Mary-Kate Olsen原創
2024-10-27 21:41:301105瀏覽

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

循環中的JavaScript 閉包:揭秘

理解閉包

Java 中的閉包允許函數從直接外部存取變數範圍,建立私有資料上下文。然而,即使封閉函數執行完畢,閉包引用的變數仍然可以存取。

循環中閉包的問題

考慮以下程式碼片段:

<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中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn