由于IE9之前的版本對(duì)JScript對(duì)象和COM對(duì)象使用不同的垃圾收集例程挥唠,因此閉包在IE這些版本中會(huì)導(dǎo)致一些特殊的問題日杈。具體來說点待,如果閉包的作用域鏈中保存著一個(gè)HTML元素搔耕,那么就意味著該元素將無法被銷毀矮嫉。
function assignHandler() {
var element = document.getElementById("someElement");
element.onClick = function() {
alert(element.id);
}
}
上例代碼創(chuàng)建了一個(gè) element 元素時(shí)間處理程序的閉包,而這個(gè)閉包則又創(chuàng)建了一個(gè)循環(huán)引用蚪拦。由于匿名函數(shù)保存了一個(gè)對(duì) assignHandler() 的活動(dòng)對(duì)象的引用杖剪,因此就會(huì)導(dǎo)致無法減少 element 的引用次數(shù)。只要匿名函數(shù)存在驰贷, element 的引用數(shù)至少也是1盛嘿,因此它所占用的內(nèi)存永遠(yuǎn)不會(huì)被回收。不過括袒,這個(gè)問題可以通過稍微改寫一些代碼來解決次兆。
function assignHandler() {
var element = document.getElementById("someElement");
var id = element.id;
element.onClick = function() {
alert(id);
}
element = null
}
在上面的代碼中,通過把 element.id 的一個(gè)副本保存在一個(gè)變量中锹锰,并且在閉包中引用該變量消除了循環(huán)引用芥炭。但僅僅做到這一步,還是不能解決內(nèi)存泄漏問題恃慧。
閉包會(huì)引用函數(shù)的整個(gè)活動(dòng)對(duì)象园蝠,而其中包含著 element 。即使閉包不直接引用 element痢士,包含函數(shù)的活動(dòng)對(duì)象中也仍然會(huì)保存一個(gè)引用彪薛。
把 element 變量設(shè)置為 null,這樣就能夠解除對(duì)DOM對(duì)象的引用良瞧,村里的減少其引用次數(shù)陪汽,確保正常回收其占用的內(nèi)存褥蚯。