javascript的做用域分兩種:全局和局部,基於咱們所學的做用域及預編譯相關知識,js做用域環境中訪問變了的權利是由內到外的內部做用域能夠得到父級做用域的變量和參數,反之則不能。也就是說外層做用域沒法獲取內層做用域下的變量和參數,一樣在不一樣的函數做用域中也是不能相互訪問到彼此的變量和參數的javascript
那麼想在函數內部想訪問另外一個函數內部的變量和參數就得用到閉包來解決這一需求。java
閉包的本質就是在一個函數內部建立另外一個函數!!!安全
在函數外面是沒法讀取到函數內的局部變量閉包
函數內部聲明變量時必定要加var,不然就聲明瞭一個全局變量。函數
閉包有三個特性:spa
1.函數嵌套函數;3d
2.函數內部能夠引用函數外部的參數和變量;blog
3.參數和變量不會被垃圾回收機制回收掉;ip
例子以下:內存
這段代碼中fun函數嵌套了一個fun2函數,return fun2 這一步把內層函數fun2返回給fun
也就等於 fun = functon fun2(){a++;console.log(a);} 而後在又把fun賦值給了num 又執行了num()
此時執行的是fun2 函數fun2裏並無a這個變量 可是他的父級函數裏有 因此他能夠獲取fun函數裏的
變量a的值
num(); //112
通常狀況下,函數fn執行完後,就應該它自己與它裏面的參數和變量一同被銷燬,但在這個例子中,匿名函數做爲fn的返回值被賦值給了fn1,至關於fn1=function(){var n = 0......},而且匿名函數裏引用着外層函數變量num,因此變量num沒法被銷燬,而變量n是每次被調用時新建立的,因此每次fn1執行完後他把屬於本身的變量連同本身一塊兒銷燬,最後就剩下num,就產生了內存消耗的問題
fn1(); //1 6
fn1(); //1 7
fn1(); //1 8
閉包的用途:
它的最大用處有兩個,一個是前面提到的能夠讀取函數內部的變量,另外一個就是讓這些變量的值始終保持在內存中,不會在f1調用後被自動清除。
閉包的優缺點:
優勢:
1.保護函數內的變量安全,保護變量不被污染;
2.一個變量長期儲存在內存中;
3.實現封裝,防止變量跑到外層做用域中,發生命名衝突;
4..匿名自執行函數,匿名自執行函數能夠減少內存消耗;
缺點:
1.內存不會被釋放,增長內存使用量;