内存泄漏关闭和简单的解决方法有什么区别?

时间:2014-02-05 21:11:32

标签: javascript performance memory-leaks

MDN regarding closure leaks阅读精彩的文档时,会看到内存泄漏关闭以及令人惊讶的简单修复的示例。

有人可以更好地解释如何简单地组合这两行(即删除el变量)来阻止泄漏吗?在我的大脑中,这两个例子在功能上是相同的。

function addHandler() {
    var el = document.getElementById('el');
    el.onclick = function() {
        this.style.backgroundColor = 'red';
    };
}
  

最简单的解决方法是不使用el变量:

function addHandler(){
    document.getElementById('el').onclick = function(){
        this.style.backgroundColor = 'red';
    };
}

3 个答案:

答案 0 :(得分:1)

第一个版本保留对局部变量“el”中DOM节点的引用;第二个没有。由于闭包的语义,这意味着绑定事件处理程序中的代码可以访问变量,因此变量保持“实时”。

现在,因为事件处理程序中的代码实际上没有引用“el”,我怀疑这是否真的是现代JavaScript环境中的内存泄漏。由于该教程中的讨论似乎是关于Internet Explorer(以及它的旧版本),因此对这种内存泄漏的关注可能仍然相关,但却越来越少。

答案 1 :(得分:1)

我没有看到你实际上在这里附上任何变量。没有内存泄漏,两个片段 相同。

答案 2 :(得分:0)

进一步澄清@Pointy的答案:'el'var使'el'DOM元素保持活着,因为它直接引用它。 'el'DOM元素的onClick事件被设置为可能引用'el'var的闭包。显示的代码没有明确地引用它在这里不能保证,因为你可以使用带有动态构建字符串的eval()来引用'el'var - 没有办法告诉浏览器。因此,'el'DOM元素的onClick反过来使'el'var保持活力。这导致JavaScript和DOM之间的循环引用,浏览器无法破坏 - 因此内存泄漏。

因为你确实想为DOM元素设置一个onClick处理程序,所以解决方案是通过在闭包范围内没有'el'var来打破这个循环。