|
|
|
|
|
閉包一個(gè)強(qiáng)大優(yōu)勢是內(nèi)部函數(shù)可以訪問外部函數(shù)的變量,但是也正是這一個(gè)特征,讓閉包容易產(chǎn)生內(nèi)存泄露的負(fù)面影響。
Javascript 允許嵌套函數(shù)(函數(shù)中的函數(shù))訪問父函數(shù)的變量,內(nèi)部函數(shù)訪問外部函數(shù)變量的過程稱為閉包。
但是一旦一個(gè)變量被任何閉包使用,它就會(huì)在該范圍內(nèi)所有閉包共享的詞法環(huán)境中結(jié)束,這可能導(dǎo)致內(nèi)存泄漏。
示例
<html>
<body>
<script>
function parentFunction(arg1) {
var a = arg1;
return function childFunction (arg2) {
alert( a +" "+ arg2);
};
};
var val = parentFunction("outer val");
val("inner val");
</script>
</body>
</html>
執(zhí)行結(jié)果
在該示例中,“childFunction
”是在“parentFunction
”外部函數(shù)中定義的內(nèi)部函數(shù)。當(dāng)使用參數(shù)“outer val”調(diào)用'parentFunction
'時(shí),外部變量a
被賦值為“outer val”。函數(shù)返回一個(gè)指向內(nèi)部函數(shù)“childFunction
”的指針,該指針包含在變量'val
'中。
即使外部函數(shù)已經(jīng)返回,外部函數(shù)的局部變量 a
仍然存在。在 javascript 中,在調(diào)用 parentFunction
的那一刻,將創(chuàng)建一個(gè)具有屬性“a
”的范圍對象。此屬性包含 arg1 的值,也稱為“outer val”。同樣當(dāng)parentFunction
返回時(shí),它會(huì)返回內(nèi)部函數(shù)(childFunction
),它包含在變量val
中。
由于內(nèi)部函數(shù)持有對外部函數(shù)變量的引用,因此具有屬性“a
”的作用域?qū)ο蟛粫?huì)被垃圾回收。
避免內(nèi)存泄漏
通過添加另一個(gè)函數(shù),將有兩個(gè)內(nèi)部函數(shù)。由于有兩個(gè)內(nèi)部函數(shù),因此沒有函數(shù)可以通過完全停止閉包來引用外部函數(shù)的變量。
當(dāng)沒有閉包時(shí),內(nèi)存泄漏的機(jī)會(huì)會(huì)減少。
<html>
<body>
<script>
window.onload=function parentFunction(){
var Obj1 = function childFunction1()
{
document.write("the leak is avoided");
};
(function childFunction2(){
var obj2 = document.getElementById("closure");
obj2.onclick=Obj1
})(); //這個(gè)是立即執(zhí)行函數(shù)
};
</script>
<input type = "button" id="closure" value ="Click Here">
</body>
</html>
執(zhí)行代碼后,按鈕將顯示如下
按下按鈕后,我們將得到如下輸出:
the leak is avoided
總結(jié)
本文通過示例,介紹了閉包如何導(dǎo)致內(nèi)存泄漏以及如何防止它。閉包雖然功能強(qiáng)大,但它有一定的負(fù)面影響,所以在編程過程中,需要考慮是否真的需要用到閉包,而不用其他的處理方式。
什么是內(nèi)存泄漏?
內(nèi)存泄漏可以定義為一塊內(nèi)存不再被應(yīng)用程序使用或需要,但由于某種原因沒有返回給操作系統(tǒng)。簡單來說,它是永遠(yuǎn)等待使用的被遺忘的數(shù)據(jù)。泄漏是所有問題的根源:速度減慢、崩潰、高延遲,甚至是其他應(yīng)用程序的問題。
下面是內(nèi)存泄漏最簡單的例子。
let arr = [];
for(let i = 5; i > 1; i++){
arr.push(i-1) // 警告!不要嘗試這個(gè)
}
該示例中,我們將運(yùn)行一個(gè)無限循環(huán),不斷地推入數(shù)組 i -1 直到填滿我們的內(nèi)存并且沒有任何東西可供我們使用。在這種情況下,垃圾收集并沒有真正起作用,因?yàn)槲覀冇羞@個(gè)數(shù)組并且我們一遍又一遍地使用這個(gè)數(shù)組,直到程序崩潰。
相關(guān)文章