2012-08-07 89 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