先從閉包特點解釋,應該更好理解.
閉包的兩個特點:
1、作為一個函式變數的一個引用 - 當函式返回時,其處於啟用狀態。
2、一個閉包就是當一個函式返回時,一個沒有釋放資源的棧區。
其實上面兩點可以合成一點,就是閉包函式返回時,該函式內部變數處於啟用狀態,函式所在棧區依然保留.
我們所熟知的主流語言,像C,java等,在函式內部只要執行了return,函式就會返回結果,然後記憶體中刪除該函式所在的區域.生命週期也就停止了.一般的js函式也是這樣.
但是有閉包特性的js函式有點特殊.
就例子來說:
function a(){
var i=0;
function b(){
alert(i++);
}
return b;
}
var c = a();
c();
這是個標準的閉包.在函式a中定義了函式b,a又return了b的值.這些可以先不管.
var c = a();
c();
這兩句執行很重要.
在var c = a();這行裡,執行了a函式,那麼肯定a經過了return.按照主流語言的函式特性,現在c的值就是a的返回值,也就是函式b.
你可以加一行alert(c); 會發現c的值為:
function b(){
alert(i++);
}
return b;
}
第二行c()的執行實際執行的就是b函式.最後不管執行的是誰,會彈出一個值為0的視窗,到此為止,所有的生命週期按理論來說就算全部結束了.
可是,如果我們再多執行一行.var c = a();c();c();第一次彈出0,第二次執行卻彈出了1.
也就是說,第一次c()後,a中的i依然保留.自然a在記憶體的棧區依然保留.
a是return過了,但是,a及內部值卻依然存在,這就是閉包.
好了,總結下,1,閉包外層是個函式.
2,閉包內部都有函式.
3,閉包會return內部函式.
4,閉包返回的函式內部不能有return.(因為這樣就真的結束了)
5,執行閉包後,閉包內部變數會存在,而閉包內部函式的內部變數不會存在.
閉包的應用場景(呵呵,複製的參考資料)
1、保護函式內的變數安全。以最開始的例子為例,函式a中i只有函式b才能訪問,而無法通過其他途徑訪問到,因此保護了i的安全性。
2、在記憶體中維持一個變數。依然如前例,由於閉包,函式a中i的一直存在於記憶體中,因此每次執行c(),都會給i自加1。
根據參考資料的應用場景,我們會自然的想到java或是c++的類.雖然JS沒有類的概念,但是有了類的相似執行結果.
另外,還有一種格式頗受爭議:(function(a,b{}))(a,b);如果你使用過jquery,並且觀察過他的程式碼,你就會很奇怪他的寫法,網上有人也把這種格式叫做閉包.