什么是閉包姆涩?
??在JavaScript的函數(Function)中,使用變量時候的查找順序是,當前方法 -> 當前方法的執(zhí)行環(huán)境 -> window作用域剥槐。查找的順序被稱為作用域鏈(prototype)
,我們常說的JS天生是繼承的宪摧,就是因為JS有作用域鏈粒竖,所有的屬性都會在作用域鏈中供你使用。
??在函數中使用變量绍刮,這個變量如果在函數執(zhí)行完畢后沒有在其他地方被使用温圆,則該變量會被刪除解除引用。但是如果你在函數中返回了一個匿名函數呢孩革,情況就會很有意思了:
var closure = (function(){
var i = 0;
return function(){
console.log(i++)
}
})();
closure();
執(zhí)行上述函數岁歉,會有什么情況呢?會不會報錯呢
執(zhí)行結果
closure()
o
closure()
1
closure()
2
...
這樣的情況是因為返回的函數和使用到父作用域的變量形成了一個閉包膝蜈,父級執(zhí)行環(huán)境的作用域鏈會被銷毀腋粥,但活動對象保留了源内,變量會一直存在于內存中,不會被清除,且計算結果也會一直被保存
那么瞻颂,如果我們一直使用閉包,當然沒有問題涩蜘,但是當我們不使用時议泵,我們因當如何去清除閉包呢?畢竟我們的內存是有限的鬓催。為了我們的性能優(yōu)化肺素,去清除閉包就尤為重要了。
如何清除閉包
簡單粗暴的直接
closure = null
就會銷毀閉包和它所使用到的活動對象宇驾。
模擬Java中類的定義
(function (){
var name = '';
Personal = function(value){
name = value;
}
Personal.prototype.getName = function(){
return name;
}
Personal.prototype.setName = function(value){
name = value;
}
})();
//由于內部Personal定義事沒有使用var倍靡,所以默認定義為全局變量
var p1 = new Personal('Michael');
p1.getName(); //Michael
p1.setName('Greg');
p1.getName(); //Greg
var p2 = new Personal('MM');
p2.getName(); //MM
p1.getName(); //MM
//由于都是使用Personal創(chuàng)建的實例,所以name就成了所有實例的共享屬性课舍。