閉包
官方解釋:所謂“閉包”,指的是一個擁有許多變量和綁定了這些變量的環境的表達式(通常是一個函數),因而這些變量也是該表達式的一部分。
個人解釋:一個函數a內部包含函數b,這個b即是閉包。調用b的時候,b的作用域鏈可以找到a的變量對象。
先看個最簡單的范例:
function a(){
var v = 1;
return function(){
console.log(v);
}
}
*******假設這個閉包函數為b********
怎么調用b?
a的作用就是return一個b函數,那么我們可以寫出這樣的表達式:
var fb = a();
這個fb,即是這個b閉包函數的引用。
fb的作用域鏈是什么?
在執行a時,會生成一個a函數的活動對象,那么在定義b的時候,作用域鏈里就會有三個對象的引用:最優先的是b函數本身的活動對象,其次是a函數的活動對象,再次是window。
fb函數如何尋找變量?
它會依次在作用域鏈存放的三個活動對象里面去找,找到即返回,都沒找到返回undefined。
不是說函數執行完了,它的活動對象就銷毀了么,照說fb執行的時候,a執行完了,怎么還可以訪問里面的值?
Javascript內存回收機制是這樣的:
“如果一個對象不再被引用,那么這個對象就會被GC回收。如果兩個對象互相引用,而不再被第3者所引用,那么這兩個互相引用的對象也會被回收。因為函數a被b引用,b又被a外的c引用,這就是為什么函數a執行后不會被回收的原因。”
a的活動對象(存儲了它內部的變量)也是對象,當fb的作用域鏈還存在對它的引用時,無法銷毀。也就是說只要fb的引用存在 ,a的活動對象一直保留。
閉包是否更加耗內存?
是的。
使用閉包的好處?
保護閉包外函數內的變量安全。因為只有閉包才能使用。
在內存中維持一個變量,不隨着外部函數執行完而銷毀。(壞處也是好處)。
這只是我個人總結,要徹底弄懂可能還得翻翻js高級編程第七章。
個人覺得算是懂了。