在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';
};
}
答案 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来打破这个循环。