據咱們所知,局部變量在函數退出以後就不佔據內存空間,但存在一種特殊的函數,能使局部變量在函數退出以後繼續佔據內存,爲外部函數所調用,這個特殊的函數就是閉包
。那麼閉包是怎麼作到將局部函數一直佔據內存的呢?看看下面的例子。閉包
function a(){
var Aitem=2;//定義局部變量item
function b() { //定義內部函數b()
alert(Aitem);
}
b();
}
a();//結果是2
複製代碼
從上能夠看出內部函數能夠讀取外部函數的局部變量。此時的內部函數的做用域僅限於外部函數a(),只有經過調用外部函數a()才能夠運行內部函數b()。當外部函數執行結束,內部函數的內存也將清除。可是若是咱們將內部函數賦給一個全局變量
,那麼內部函數將從局部變量
轉化成全局變量
。即便外部函數退出了,做爲全局變量的內部函數也將保存在內存中。那麼如何讓內部函數成爲全局變量呢?函數
function a(x){
var Aitem=2;//定義局部變量item
return function b(y) { //a函數結果返回一個b函數
alert(x+y+(++Aitem));
}
}
var closure=a(1);//將a(1)return的結果b()賦給全局變量,closure=b(y){ alert(1+y+(++Aitem))}
closure(1);//彈出5;closure(1)=b(y){ alert(1+1+(++2))}
closure(1);//彈出6;closure(1)=b(y){ alert(1+1+(++3))}
複製代碼
上例中的closure()函數即閉包
。第一次closure(1)中Aitem=2
,第二次closure(1)中Aitem=3
,能夠看出item
這個局部變量在a()退出之後並無被清除,而是像一個全局變量同樣一直保存在內存中。這就是閉包的神奇所在。closure()閉包依賴於b(y),而b(y)又是a(x)的局部函數,故closure()閉包能夠實時訪問a(x)的局部變量。若是沒有將內部函數裝化成全局變量的話,就形不成閉包,請看下面的例子:spa
function a(x){
var Aitem=2;//定義局部變量item
function b(y) { //定義局部函數b
alert(x+y+(++Aitem));
}
b(1);//在a()內部運行b(1);即alert(x+1+(++2))
}
a(1);//彈出5;即alert(1+1+(++2))
複製代碼
上例沒有將局部函數b()賦給全局變量,在a(1)運行之後b()就不復存在,Aitem也無從獲取。code
閉包是能夠讀取其餘函數內部變量的函數,是外部函數和內部函數的一座橋樑。內存
閉包擁有兩個做用:作用域
閉包的缺點:it