首頁 > web前端 > js教程 > 主體

[JavaScript] 在幾秒鐘內理解閉包

王林
發布: 2024-08-26 21:31:35
原創
895 人瀏覽過

[JavaScript] Understand closures in  seconds

雖然閉包是 JavaScript 中的基本概念,但新手可能會發現它們模糊且難以掌握。具體來說,如果沒有任何實際經驗,ECMA 標準的定義可能很難理解。因此,我們不會在這篇文章中花很多篇幅來解釋閉包的概念,而是透過使用實際程式碼讓您輕鬆理解。

1. 關閉

function A(name){
    function B(){
       console.log(name);
    }
    return B;
}
var C = A("Closure");
C();//Closure
登入後複製

這是最簡單的閉包。

現在我們已經了解了基礎知識,讓我們簡要地研究一下它與典型函數的差異。以下是上述程式碼翻譯成自然語言後的樣子:

  1. 定義一個普通函數 A,帶有參數名稱
  2. 在A定義一個正規函數B,在B中引用外部變數名稱
  3. 在A返回B
  4. 執行A並將結果賦值給變數C
  5. 運行C

一條語句可以封裝這五個運算:

函數A內部的函數B和變數名稱被函數A外部的變數C引用。

經過一點修改,語句定義了一個閉包,如下:

當內部函數被外部函數外部的變數引用時,就形成了閉包。

因此,執行以上五個操作就定義了一個閉包。

閉包的用途

在了解閉包的用途之前,我們先來了解 JavaScript 的 GC(垃圾收集)機制。

在 JavaScript 中,當一個物件不再被引用時,它會被 GC 回收,否則,它會繼續保留在記憶體中。

在上面的例子中,B 依賴 A,因為 B 是在 A 內部定義的,而 A 被 C 間接引用,因為外部變數 C 引用了 B。

即A不會被GC回收,會繼續保存在記憶體中。為了證明這個推理,我們稍微改進一下上面的例子。

function A(){
    var count = 0;
    function B(){
       count ++;
       console.log(count);
    }
    return B;
}
var C = A();
C();// 1
C();// 2
C();// 3
登入後複製
  1. 如果我們呼叫 var C = A();,A 就會被執行,建立一個計數變數和一個內部函數 B。由於 A 回傳 B,所以 C 變數實際上擁有 B 的引用。然後函數 B 可以存取計數 A 中的變數。
  2. 函數 B 可以存取 A 中的 count 變量,因為 B 是閉包。這是因為 B 是一個閉包,而閉包保留了創建它們的上下文(例如局部變數)。
  3. 當呼叫 C() 時,它實際上呼叫了函數 B。每次呼叫 C() 時,B 都會遞增 count 的值並將該值顯示在控制台上。
  4. A 的執行上下文在 B 建立時結束,但只要 B 引用其局部變數(例如 count),A 的局部變數就不會被回收。
  5. 只有當B不再被引用時,A中的count變數和其他局部變數才會被恢復。在這個例子中,由於C仍然引用B,所以count的值沒有恢復,A的執行上下文也沒有恢復。

為什麼計數沒有重置?

關閉機制:

  • 閉包保留 count 的狀態並使其可供內部函數 B 存取。即使 A 的執行上下文終止,count 的狀態仍保留在記憶體中,因為 B 繼續引用該狀態。
  • 每次呼叫 B:每次呼叫 C() 實際上都是呼叫 B(),它使用閉包中儲存的計數,並且不會重新初始化它。

因此,如果您在模組中定義了一些變量,並且希望將這些變量保留在內存中但又不想“污染”全局變量,則可以使用閉包來定義該模組。

以上是[JavaScript] 在幾秒鐘內理解閉包的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板