在最近的一次采访中,有人问我:“像这段代码一样,在引用 DOM 元素时使用闭包有什么危险?”
var firstNameValue = (function(elementId) {
var firstName = document.getElementById(elementId);
return firstName.value;
})("firstName");
显然,我不知道的是,上面的代码在 IE 中造成了内存泄漏。给定的基本原理相当模糊,我不明白,但显然这可能只适用于较旧的 IE 版本?
任何人都可以详细说明这一点吗?
IE 内部用于处理由 DOM 分配的内存或为 DOM 分配的内存的垃圾收集器不知道如何释放由 JScript 引擎分配的可能悬空的内存。因此,它只是忽略这些事情。
因此,您将事件处理程序绑定到 DOM 元素(或类似的东西),并且您的事件处理程序是在某个其他函数的调用中创建的函数,并且该其他函数有一个本地数组,其中包含十亿个内容,好吧,在 DOM 元素本身被垃圾化很久之后,甚至在page包含它的那个已经被释放了(我想;已经有一段时间了)。
function bindHandler(domElement) {
var hoHumWhatever = generateGiganticObjectNow();
domElement.onclick = function() {
alert("oww you clicked me");
};
}
现在“hoHumWhatever”变量被保留在闭包中。当重新加载页面或修改 DOM 导致元素被丢弃时,DOM 垃圾收集器将无法对指向 JScript 拥有的内存的属性执行任何操作。另一方面,JScript 不知道 DOM 节点已被释放,因此它认为闭包内存仍然被引用。
我承认这在某些细节上可能不准确,但这是基本问题。很多人都写过关于此事的文章,包括 Crockford 先生和(我认为)quirksmode 的 ppk。
edit — 更仔细地重读后你发布的代码,我认为might be类似但相反情况的示例:小函数返回对 DOM 值的一部分的引用,因此也许有人说 JScript 将挂在 DOM 内存上(而不是反之亦然)。现在,在这种特殊情况下,我有点怀疑,因为除了对 DOM 属性的简单引用之外,我看不出有什么东西是如何从该闭包中“逃脱”的,该属性应该是一个原始字符串实例,因此实际上应该是这样的不会造成问题。然而这些事情可能具有欺骗性,所以我就坐在这里挠头。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)