1. 程式人生 > >JS 閉包的理解

JS 閉包的理解

過程 總結 改變 就會 我們 外部變量 永遠 執行 因此

先寫一個簡單閉包函數

function A(){
    function B(){
       console.log(Hello Closure!);
    }
    return B;
}
var C = A();
C();// Hello Closure!

這個閉包函數的執行過程為

1、定義普通函數 A

2、在 A 函數內部定義 普通函數 B

3、在 A 函數中返回 B

4、執行 A ,並把 A 返回的結果賦值給變量 C

5、執行 C

總結起來就是:

函數A的內部函數B被函數A外的一個變量 c 引用。

那麽閉包的定義就就是:

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

註意!閉包和內存泄漏和內存回收之間的關系

內存回收:avaScript是一種具有垃圾回收機制的語言——對象在創建時分配內存,當一個對象不再被引用的時候,這個對象就會被瀏覽器回收,

否則這個對象就會一直保存在內存中。

內存泄漏是指我們已經無法再通過js代碼來引用到某個對象,但垃圾回收器卻認為這個對象還在被引用,因此在回收的時候不會釋放它。

致了分配的這塊內存永遠也無法被釋放出來。如果這樣的情況越來越多,會導致內存不夠用而系統崩潰。

在上述例子中,B 定義在 A 中,因此 B 依賴於 A ,而外部變量 C 又引用了 B , 所以A間接的被 C 引用。

也就是說,A 不會被 GC 回收,會一直保存在內存中。

上述例子進行改進

function A() {
    var count = 0;
    function B() {
       count ++;
       console.log(count);
    }
    return B;
}
var C = A();
C();// 1
C();// 2
C();// 3

count 是函數A 中的一個變量,它的值在函數B 中被改變,函數 B 每執行一次,count 的值就在原來的基礎上累加 1 。因此,函數A中的 count 變量會一直保存在內存中。

當我們需要在模塊中定義一些變量,並希望這些變量一直保存在內存中但又不會 “汙染” 全局的變量時,就可以用閉包來定義這個模塊

JS 閉包的理解