2012-08-07 88 views
0

我讀在其中要求保護的下列代碼將導致內存泄漏在IE中早於版本8.爲什麼此代碼在IE中導致內存泄漏?

function setHandler() { 
    var elem = document.getElementById('id') 
    elem.onclick = function() { /* ... */ } 
} 

作者還提供的修補程序,以防止內存泄漏online JavaScript tutorial

function setHandler() { 
    var elem = document.getElementById('id') 
    elem.onclick = function() { /* ... */ } 
    elem=null; 
} 

爲什麼原始代碼會導致內存泄漏,並且修復如何防止它?

+3

文章解釋它:*的Internet Explorer之前的版本8無法清潔循環引用之間DOM對象和JavaScript *和答案一樣好:*我們分配elem = null,所以處理程序不再引用DOM元素。圓形鏈接被打破。* – Blender 2012-08-07 02:31:23

回答

3

該文給出了很好的解釋,問題是IE和循環引用。

這意味着,當你這樣做:

function setHandler() { 
    var elem = document.getElementById('id') // (1) 
    elem.onclick = function() { /* ... */ } //(2) 
} 

函數的第一行refencing第二個,第二個是參考第一和導致IE不能釋放內存,它分配給創建elem變量。

你被「毀」 ELEM的價值打破了明確去除第二參考,參考,在該行

elem = null 

使IE可以釋放內存

第二參考是因爲closure存在問題,onclick中的內部函數可以訪問elem(它存在於函數作用域中),所以它在那裏「鎖定」。

換句話說,有兩個對elem的引用,一個是在var語句中創建的,另一個是在onclick函數中創建的,並且該引用在釋放閉包之前不會被釋放。

你可以找到更多信息hereherethis stack overflow answer

+0

:你的意思是功能(1)和(2)的循環引用嗎?但是如果這是真的,爲什麼'set elem = null'會打破這個? – hguser 2012-08-07 02:40:40

+0

我會用更多信息編輯答案 – NicoSantangelo 2012-08-07 02:47:46

+0

@hguser - 即使在setHandler()函數完成後,賦給'onclick'的嵌套函數也可以訪問elem變量,所以如果你用'elem'離開'elem'引用DOM元素,您將獲得循環引用。將該變量設置爲null可消除此問題。 – nnnnnn 2012-08-07 02:49:46