舉一個例子來說明閉包:
function A(){
var a=0;
function B(){
a=a+1;
console.log(a);
}
return B;
}
var m=A();
var n=m();
上述代碼中每次執(zhí)行m(),a的值都會加1。
例子的原理
因為上述代碼中當執(zhí)行A()的時候,此時執(zhí)行環(huán)境為函數(shù)A的函數(shù)執(zhí)行環(huán)境,作用域鏈的最前端為A的活動對象,然后是全局變量對象。當函數(shù)A執(zhí)行完畢后,本應該銷毀A的活動對象,但因為返回結果為B,也就是此時全局變量m中保存的是函數(shù)B,所以把函數(shù)B帶入了全局環(huán)境中,但是B的作用域鏈需要引用A,所以A的活動對象并沒有銷毀。當在全局中執(zhí)行B時,此時的作用域鏈依次為B的活動對象,A的活動對象,全局活動對象。
閉包的神奇之處:
外層的函數(shù)執(zhí)行后,本應該銷毀作用域,并且JS的垃圾回收機制將其內(nèi)存空間進行回收,但是閉包阻止了這件事。因為內(nèi)層的函數(shù)在其詞法作用域以外的地方被執(zhí)行,而其內(nèi)層函數(shù)又需要引用外層函數(shù)的作用域,所以外層函數(shù)執(zhí)行后,并沒有銷毀作用域,垃圾回收機制也沒有對內(nèi)存空間進行回收。