[Javascript]:如果没有正确删除,使用CreateElement方法创建的元素是否会导致内存泄漏?

[Javascript]:如果没有正确删除,使用CreateElement方法创建的元素是否会导致内存泄漏?,javascript,Javascript,我使用createElement方法创建元素,并将其附加到某个父元素。稍后,我将清除父元素的innerHTML。这会导致内存泄漏吗?创建的元素会发生什么变化?如果这是内存泄漏,如何处理?。此外,如果有任何回调函数附加到元素,是否需要分离它 var spanelem = document.createElement('span'); spanelem.onclick = function(){ CallMe(); }; var parentdiv = document.getElementById

我使用createElement方法创建元素,并将其附加到某个父元素。稍后,我将清除父元素的innerHTML。这会导致内存泄漏吗?创建的元素会发生什么变化?如果这是内存泄漏,如何处理?。此外,如果有任何回调函数附加到元素,是否需要分离它

var spanelem = document.createElement('span');
spanelem.onclick = function(){
CallMe();
};
var parentdiv = document.getElementById('ParentCnt');
parentdiv.appendChild(spanelem);
.....

.....
parentdiv.innerHTML = " "; //is this memory Leak ? what happens to spanelem?
视情况而定

如果您有您给出的代码-spanElem仍然存在于内存中(如果
var spanElem
在全局范围内,并且您没有执行
spanElem=null
),因为存在对对象的可访问引用

否则,如果spanElem的onClick处理程序中只有一个引用,那么它只会在IE8中出现内存泄漏。所有现代浏览器都会处理这种情况,并在垃圾收集时清理内存

我想您的意思不是正确的代码,而是原则——在这种情况下,您可以检查在其词法环境中是否没有其他处理程序具有指向spanElem的链接,如果是,您可以通过添加

spanelem=null

之后

parentdiv.appendChild(spanelem)

检查

附言。 如果运行下一个代码

var spanelem = document.createElement('span');
spanelem.onclick = function(){
CallMe();
};
var parentdiv = document.getElementById('ParentCnt');
parentdiv.appendChild(spanelem);

parentdiv.innerHTML = '';

console.log(spanelem);
您会发现spanelem仍然存在(如果您运行,它将是相同的)
setTimeout(function(){console.log(spanelem);},9999);//这里有很大的延迟
)-但唯一的原因是对于下面的代码,我们保存了对spanelem对象的引用,这样gc就不会删除该对象。如果我们不使用它-一般来说,gc将删除它正在运行的对象,如果存在有关垃圾收集的问题,则要缓解该问题,需要为垃圾收集器的目标创建一个关闭

一旦从变量环境和词法环境中删除了对变量的所有引用,则该变量符合收集条件

这意味着,将变量封装在其自身的执行上下文中将提供对这些环境的最小暴露。这可以通过立即调用的函数表达式(IIFE)实现


…续:此时,唯一剩下的引用是通过DOM。使用appendChild会导致文档回流,因此,如果发生任何其他导致回流的情况,例如.innerHTML,则可以删除该条目。稍后,使用
parentdiv.innerHTML=“
将导致条目被删除,垃圾收集器最终将以自己的速度删除内存分配(如果需要)。

非常感谢您的快速响应。spanelem在局部范围内(在函数中),因此,如果我这样做spanelem=null;孩子出生后,我不必担心内存泄漏,对吧?是的。若你们有现代浏览器,你们可以保持代码不变。如果我非常感谢您。@vivek:如果
spanelem
在本地作用域中,您只需等待作用域消失(例如,当函数返回且没有闭包保留引用时)。您不需要取消它。为什么您认为
document.createElement
会做任何特殊的事情?不,它的工作原理与您通过
innerHTML
或类似方式创建元素并通过DOM选择器查询将其分配给
spanelem
完全相同。@Bergi:谢谢您的建议。问题不是创建元素,我真正想知道的是,当我们设置
innerHTML=“
”时,元素是否从内存中清除。在C++中工作很长时间,我们很难消化这个事实,我们不必费心去清理这些对象:从Travis answer中还认识到一个非常重要的事实,即调用innerHTML会立即导致文档回流。这些元素至少不再从DOM中引用,设置
innerHTML
会完全删除它们。是否从内存中清除取决于引用它们的其他内容(例如,您的全局?
spanelem
变量)。是。理解这个概念。感谢所有人的帮助:)谢谢你给我的建议,让我用IIFE来定义变量的范围。我从您的解释中了解到,对于每个元素,我们都通过变量和DOM进行引用。如果我们设法删除所有通过变量的引用,即通过使用局部作用域变量或通过将变量设置为null,那么其余的将自动管理,即当发生回流时,垃圾收集器将完成其工作…@vivek-是的,这是正确的。如果删除了所有引用(变量和DOM),那么对象将符合GC的条件(不保证运行GC)。
(function(){
    var spanelem = document.createElement('span');
    spanelem.onclick = function(){
        CallMe();
    };
    var parentdiv = document.getElementById('ParentCnt');
    parentdiv.appendChild(spanelem);
})()
//CONT'D