Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/381.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 引用闭包中的DOM元素导致IE内存泄漏?_Javascript_Internet Explorer_Dom - Fatal编程技术网

Javascript 引用闭包中的DOM元素导致IE内存泄漏?

Javascript 引用闭包中的DOM元素导致IE内存泄漏?,javascript,internet-explorer,dom,Javascript,Internet Explorer,Dom,在最近的一次采访中,我被问到,“像这样引用DOM元素时使用闭包有什么危险?” 显然,在我不知道的情况下,上面的代码在IE中造成了内存泄漏。给出的理由非常模糊,我不明白,但显然这可能只适用于旧的IE版本 任何人都可以对此进行详细说明。IE中用来处理DOM分配的内存的垃圾收集器不知道如何释放JScript引擎分配的内存。因此,它忽略了这些事情 所以你把一个事件处理程序绑定到一个DOM元素(或类似的东西),你的事件处理程序是在调用其他函数的过程中创建的一个函数,而另一个函数有一个本地数组,里面有10亿

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

显然,在我不知道的情况下,上面的代码在IE中造成了内存泄漏。给出的理由非常模糊,我不明白,但显然这可能只适用于旧的IE版本


任何人都可以对此进行详细说明。

IE中用来处理DOM分配的内存的垃圾收集器不知道如何释放JScript引擎分配的内存。因此,它忽略了这些事情

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

现在,在闭包中维护了“hoHumWhatever”变量。当重新加载页面或修改DOM以丢弃元素时,DOM垃圾收集器将无法处理指向JScript拥有的内存的属性。另一方面,JScript不知道DOM节点已被释放,因此它认为闭包内存仍然被引用

我承认这在某些细节上可能不准确,但这是基本问题。很多人都写过这方面的文章,包括Crockford先生和(我想)quirksmode的ppk


编辑-仔细阅读您发布的代码后,我认为这可能是一个类似但相反的例子:小函数返回对DOM值一部分的引用,因此可能有人说JScript将挂起DOM内存(而不是相反)。现在,在这个特殊的例子中,我有点怀疑,因为除了对DOM属性的简单引用之外,我看不到任何东西是如何从闭包中“转义”的,DOM属性应该是一个基本字符串实例,因此它实际上不应该引起问题。然而,这些事情可能是骗人的,所以我只能坐在这里搔搔头。

以下代码不会创建任何闭包(见下文)或内存泄漏

对IE6的一点调查表明,该代码不会造成内存泄漏。我用一大块Lorem ipsum和唯一ID添加了1000个div,然后根据上面的代码运行了1000个匿名函数,每次我刷新页面时,它都顽固地返回到打开页面之前使用的内存。即使在页面上增加数千个元素,使其超过100mb,也没有让它感到不安

因此,要么这是一个技巧性的问题(即,正确的答案是“没有持久闭包,没有循环引用,因此没有内存泄漏”),要么是想出这个问题的人写得不正确

如果这不是一个骗人的问题,看看你能不能让写这个问题的人或问这个问题的人给你一个实际的演示

结束

闭包的简单解释是 ECMAScript允许内部 功能;函数定义和 内部的函数表达式 这个功能预示着其他功能。 这些内在功能是 允许访问所有本地 变量、参数和声明的 内部功能在其外部 功能。当 其中一个内部功能是 在中的函数外部可访问 它被控制住了,这样它就可以 在外部函数之后执行 他回来了。在这一点上,它仍然 可以访问局部变量, 参数与内部函数 声明其外部功能。 这些局部变量、参数和 函数声明(最初)具有 当 返回的外部函数可能是 与内部功能相互作用


Richard Cornford等人,“Javascript闭包”

谈到“堆栈溢出”:)我同意你的观点,我需要看到它证明上述操作会造成泄漏。没有闭包,“小函数”(有些人称为iife)不会持久化,即使它持久化了,它也不会引用其外部范围中的任何变量(尽管它确实获得了对DOM元素的引用)。唯一可能的泄漏是来自DOM引用,如果这造成了泄漏,那么您究竟如何避免它?IE内存泄漏的主要问题是涉及DOM元素的循环引用(根据您的示例),但这已经被修复(据我所知)。提问者要么非常愚蠢,要么非常聪明。哑,因为没有闭包或内存泄漏,整个过程相当于:
var firstNameValue=document.getElementById('firtName').value。或者非常聪明,因为提到闭包和内存泄漏会分散人们对真正问题的注意力——代码不必要的复杂性。然而,正如@RobG在他的回答中所说的,我不认为这会导致旧浏览器内存泄漏。下面的MSDN页面列出了一系列在IE7和更早版本中可能导致内存泄漏的测试用例-我看不到包含此模式。
var firstNameValue = (function(elementId) {
    var firstName = document.getElementById(elementId);
    return firstName.value;
})("firstName");
function bindHandler(domElement) {
  var hoHumWhatever = generateGiganticObjectNow();

  domElement.onclick = function() {
    alert("oww you clicked me");
  };
}
var firstNameValue = (function(elementId) {
    var firstName = document.getElementById(elementId);
    return firstName.value; 
})("firstName");