在闭包中引用DOM元素的IE内存泄漏?

Dot*_*ion 2 javascript internet-explorer dom

在最近的一次采访中,我被问到:"在引用DOM元素时使用闭包有什么危险,就像这个代码一样?"

var firstNameValue = (function(elementId) {
    var firstName = document.getElementById(elementId);
    return firstName.value;
})("firstName");
Run Code Online (Sandbox Code Playgroud)

显然,我不知道,上面的代码在IE中创建了内存泄漏.给定的理由非常模糊,我不理解它,但显然这可能只适用于较旧的IE版本?

有人可以详细说明吗?

Poi*_*nty 5

IE中用于处理由/为DOM分配的内存的垃圾收集器不知道如何释放可能由JScript引擎分配的内存.因此,它只是忽略了这些事情.

所以你将一个事件处理程序绑定到一个DOM元素(或类似的东西),你的事件处理程序是在一些其他函数的调用内创建的函数,而另一个函数有一个包含十亿个东西的本地数组,嗯,在DOM元素本身被废弃之后很长时间内,这些数十亿的东西一直存在,甚至在包含它的页面被释放后很久(我想;已经有一段时间了).

function bindHandler(domElement) {
  var hoHumWhatever = generateGiganticObjectNow();

  domElement.onclick = function() {
    alert("oww you clicked me");
  };
}
Run Code Online (Sandbox Code Playgroud)

现在闭包中保持了"hoHumWhatever"变量.当重新加载页面或修改DOM以使元素被丢弃时,DOM垃圾收集器将无法对指向JScript拥有的内存的属性执行任何操作.另一方面,JScript不知道DOM节点已被释放,因此它认为仍然引用了闭包内存.

我承认在某些细节上这可能是不准确的,但这是基本问题.各种各样的人都写过这个,包括Crockford先生和(我认为)ppk在quirksmode.

编辑 - 更仔细地重新阅读你发布的代码,我认为这可能是类似但相反情况的一个例子:little函数返回对DOM值的一部分的引用,所以也许有人说JScript会挂在DOM上记忆(而不是反之亦然).现在,在这种特殊情况下,我有点怀疑,因为除了对DOM属性的简单引用之外,我没有看到有什么东西从该闭包中"逃脱",DOM属性应该是一个原始字符串实例,所以它真的不应该引起问题.这些事情可能具有欺骗性,但我只会坐在这里划伤我的头脑.