19.js中閉包
js中閉包
var name = "Microsoft";
function funcA(){
var name = "Google";
alert(name);
return function(){
name = "Facebook";
alert(name);
};
}
var o = funcA(); //Google
alert(name); //Microsoft
o(); //Facebook
******************
執行完後,執行流就會離開funcA, 那麼funcA的變量對象就應該被銷燬了。
作用域鏈的創建規則是複製上一層環境的作用域鏈,並將指向本環境變量對象的指針放到鏈首;
******************
匿名函數的作用域鏈應該有三個元素,第一個是匿名函數的變量對象指針,第二個是funcA的變量對象指針,第三個是全局變量對象指針。根據搜索算法,首先搜索匿名函數的變量對象,顯然這個對象中不存在name,然後搜索funcA的變量對象,這裏面有個“name”,因此將其作爲name變量返回,搜索終止,所以,匿名函數引用的是funcA內定義的“name”變量而非全局變量。
var o = funcA();
執行完後,執行流就會離開funcA, 那麼funcA的變量對象就應該被銷燬了,funcA內定義的變量name就應該不存在了,爲什麼在後面還可以訪問到呢?要解釋這個問題,請回想上文一句話:作用域鏈的創建規則是複製上一層環境的作用域鏈,並將指向本環境變量對象的指針放到鏈首;根據這句話我們知道匿名函數的作用域鏈有三個元素,引用了三個變量對象(上文有說),這裏要注意,返回的匿名函數賦值給了變量o,而變量o是一個全局變量,在funcA執行完成後不會被銷燬。當賦值的時候,匿名函數的作用域鏈已然建立,並且此作用域鏈引用了funcA的變量環境,因此,當funcA執行完畢後,其執行變量和作用域鏈確實被銷燬了,但是其變量對象沒有被銷燬,因爲匿名函數的作用域鏈對其有引用,其無法被垃圾回收機制銷燬。當funcA執行完成後funcA的Scope chain早就銷燬了,但是其變量對象(紅色表示),因爲被匿名函數的Scope chain引用了,所以沒有銷燬。因此,匿名函數可以訪問其成員,當匿名函數執行完成後,它會連同匿名函數的Scope chain一起被銷燬。
閉包就是能訪問另一個函數作用域中變量的函數。
因爲閉包通常通過匿名函數實現,所以經常有人將閉包和匿名函數兩個名詞混用。閉包的優點很明顯,就是可以訪問另一個函數域中的變量,缺點也明顯,比較耗內存(因爲同時保持了N個變量對象)。
var name = "Microsoft";
function funcA(){
var name = "Google";
alert(name);
return function(){
name = "Facebook";
alert(name);
};
}
var o = funcA(); //Google
alert(name); //Microsoft
o(); //Facebook
******************
執行完後,執行流就會離開funcA, 那麼funcA的變量對象就應該被銷燬了。
作用域鏈的創建規則是複製上一層環境的作用域鏈,並將指向本環境變量對象的指針放到鏈首;
******************
匿名函數的作用域鏈應該有三個元素,第一個是匿名函數的變量對象指針,第二個是funcA的變量對象指針,第三個是全局變量對象指針。根據搜索算法,首先搜索匿名函數的變量對象,顯然這個對象中不存在name,然後搜索funcA的變量對象,這裏面有個“name”,因此將其作爲name變量返回,搜索終止,所以,匿名函數引用的是funcA內定義的“name”變量而非全局變量。
var o = funcA();
執行完後,執行流就會離開funcA, 那麼funcA的變量對象就應該被銷燬了,funcA內定義的變量name就應該不存在了,爲什麼在後面還可以訪問到呢?要解釋這個問題,請回想上文一句話:作用域鏈的創建規則是複製上一層環境的作用域鏈,並將指向本環境變量對象的指針放到鏈首;根據這句話我們知道匿名函數的作用域鏈有三個元素,引用了三個變量對象(上文有說),這裏要注意,返回的匿名函數賦值給了變量o,而變量o是一個全局變量,在funcA執行完成後不會被銷燬。當賦值的時候,匿名函數的作用域鏈已然建立,並且此作用域鏈引用了funcA的變量環境,因此,當funcA執行完畢後,其執行變量和作用域鏈確實被銷燬了,但是其變量對象沒有被銷燬,因爲匿名函數的作用域鏈對其有引用,其無法被垃圾回收機制銷燬。當funcA執行完成後funcA的Scope chain早就銷燬了,但是其變量對象(紅色表示),因爲被匿名函數的Scope chain引用了,所以沒有銷燬。因此,匿名函數可以訪問其成員,當匿名函數執行完成後,它會連同匿名函數的Scope chain一起被銷燬。
閉包就是能訪問另一個函數作用域中變量的函數。
因爲閉包通常通過匿名函數實現,所以經常有人將閉包和匿名函數兩個名詞混用。閉包的優點很明顯,就是可以訪問另一個函數域中的變量,缺點也明顯,比較耗內存(因爲同時保持了N個變量對象)。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.