摘抄:https://blog.csdn.net/Q846169253/article/details/81148290
閉包就是能夠讀取其它函數(shù)內(nèi)部變量的函數(shù)浑此。
由于在Javascript語言中贾漏,只有函數(shù)內(nèi)部的子函數(shù)才能讀取局部變量,因此可以把閉包簡單理解為“定義一個函數(shù)內(nèi)部的函數(shù)"
本質(zhì)上驯镊,閉包就是將函數(shù)內(nèi)部和函數(shù)外部連接起來的一座橋梁萤皂。
function makeFunc(){
var name = "Mozilla";
function displayName(){
alert(name)
}
return displayName
}
const myFunc = makeFunc();
myFunc()
試一試結(jié)果:js中的函數(shù)形成了閉包撒穷,在本例子中,myFunc是執(zhí)行makeFunc時創(chuàng)建的displayName函數(shù)實例的引用裆熙。displayName的實例維持了一個對它的詞法環(huán)境(變量name存在與其中)的引用端礼,因此,當(dāng)myFunc被調(diào)用時入录,變量name仍然可用
function makeAdd(x){
return function(y){
return x + y
};
}
var a = makeAdd(5);
var b = makeAdd(10);
console.log(a(2)); //7
console.log(b(2)); //12
閉包的原理
借助函數(shù)的立即執(zhí)行蛤奥、參數(shù)以及函數(shù)的return返回值,多創(chuàng)建了一層作用域僚稿。從而實現(xiàn)外部函數(shù)持續(xù)被引用而不能釋放內(nèi)存空間喻括,將值存儲下來
閉包的作用
閉包就是將函數(shù)內(nèi)部和函數(shù)外部連接起來的一座橋梁。使得外部函數(shù)可以讀取內(nèi)部函數(shù)的變量贫奠,這些變量的值始終保持再內(nèi)存中,不會被垃圾回收器回收望蜡。
閉包如何從外部的作用域讀取到內(nèi)部作用域的東西
那就是在函數(shù)的內(nèi)部唤崭,再定義一個函數(shù)。將內(nèi)部函數(shù)傳遞到所在詞法作用域以外
閉包的優(yōu)點
- 避免全局變量被污染
- 方便調(diào)用上下文的局部變量
- 加強封裝性
閉包的缺點
- 閉包常駐內(nèi)存脖律,內(nèi)存消耗很大
- 可能導(dǎo)致內(nèi)存泄漏
解決方案:在退出函數(shù)之前谢肾,將不使用的局部變量全部刪除
如何刪除?
// 普通變量:將變量置為undefined
var tt = 111;
tt = undefined;
//帶有屬性或者方法的, 用delete刪除屬性或方法
delete tt.name
內(nèi)存泄漏
一塊被分配的內(nèi)存既不能被使用小泉,也不能回收芦疏,從而影響性能冕杠,從而導(dǎo)致程序崩潰。
內(nèi)存泄漏起因:一般使用技術(shù)系統(tǒng)來處理內(nèi)存酸茴,每個對象根據(jù)被引用對象多少來計數(shù)分预,當(dāng)計數(shù)為零時,該對象就會被銷毀薪捍,釋放內(nèi)存笼痹。而當(dāng)兩個對象循環(huán)引用時,計數(shù)始終為1酪穿,則永久性地占著內(nèi)存凳干。而閉包實際上非常容易造成js對象的dom對象的循環(huán)引用
function ex(){
var element = document.getElementByID('div1');
element.onclick=function(){
alert("aaa")
}
}
ex()用匿名函數(shù)創(chuàng)建閉包,該DOM對象的onclick屬性引用了匿名函數(shù)閉包被济,而閉包可以引用外部函數(shù)example()的整個活動對象救赐,包括element;DOM(div1.onclick)--->JS(element) 由此形成了Javascript對象和DOM對象的隱藏循環(huán)引用只磷。
造成的內(nèi)存泄漏
解決方法:
在js代碼段運行完之后將形成循環(huán)引用的js對象設(shè)置為空
function example(){
var element = document.getElementByID("div1");
element.onclick = function(){
alert("This is a leak!")
}
element = null; //添加的語句
}
垃圾回收機制
找到那些不再繼續(xù)使用的變量经磅,然后釋放其占用的內(nèi)存,垃圾收集器會按照固定的事件間隔周期性進(jìn)行這一操作
兩種方法———標(biāo)記清除和引用計數(shù)
- 標(biāo)記清除
垃圾收集器在運行的時候會給存儲在內(nèi)存中的所有變量都加上標(biāo)記喳瓣,然后馋贤,它會去掉環(huán)境中的變量的標(biāo)記和被環(huán)境中的變量引用的變量的標(biāo)記,此后畏陕,如果變量再被標(biāo)記則表示此變量準(zhǔn)備被刪除
另一種解釋:
當(dāng)變量進(jìn)入執(zhí)行環(huán)境時標(biāo)記為“進(jìn)入環(huán)境”配乓,當(dāng)變量離開執(zhí)行環(huán)境時則標(biāo)記為“離開環(huán)境”,而標(biāo)記為“離開環(huán)境的變量則可以被回收” - 引用計數(shù)
跟蹤記錄每個值被引用的次數(shù)惠毁,當(dāng)聲明一個變量并將一個引用類型的值賦值給該變量時犹芹,這個值的引用次數(shù)就是1,如果這個值再被賦值給另一個變量鞠绰,則引用冊數(shù)加1. 相反腰埂,如果一個變量脫離了該值的引用,則該值引用次數(shù)減1蜈膨,當(dāng)次數(shù)為0時屿笼,當(dāng)次數(shù)為0時,就會等待垃圾回收器的回收翁巍。