如果我从body中删除父元素,它会完全从内存中删除吗?
如果你的parentElm、child1和child2变量不再在作用域内或者你已经将它们设置为其他值,那么是的。
如果我从body中删除父元素,它的子元素是否会被垃圾收集器自动清除?还是我需要手动删除子元素?
如果你的child1和child2变量不再在作用域内或者你已经将它们设置为其他值,那么是的,删除父元素就足以删除子元素并允许它们被清理。
在上面的代码中使用innerHTML是一个好的方法吗(child1.innerHTML =“Hello”;)?
这是可以的,也是常见的做法。
所以这里没有内存泄漏,例如:
function addParagraphs() {
var parentElm = document.createElement("div");
var child1 = document.createElement("p");
var child2 = document.createElement("p");
parentElm.id = "parent";
child1.id = "child1";
child2.id = "child2";
child1.innerHTML = "Hello";
child2.innerHTML = "world";
parentElm.appendChild(child1);
parentElm.appendChild(child2);
document.body.appendChild(parentElm);
}
function removeElement(element) {
if (element.remove) {
element.remove();
} else if (element.parentNode) {
element.parentNode.removeChild(element);
}
}
addParagraphs();
removeElement(document.getElementById("parent"));
因为addParagraphs
中的变量都可以被回收,所以这种做法是可行的。
但是,如果你在这些变量上创建了一个闭包并保持它,那么它会使元素在内存中的存储时间比你预期的要长:
function addParagraphs() {
var parentElm = document.createElement("div");
var child1 = document.createElement("p");
var child2 = document.createElement("p");
parentElm.id = "parent";
child1.id = "child1";
child2.id = "child2";
child1.innerHTML = "Hello";
child2.innerHTML = "world";
parentElm.appendChild(child1);
parentElm.appendChild(child2);
document.body.appendChild(parentElm);
return function() {
console.log("Hi there");
};
}
function removeElement(element) {
if (element.remove) {
element.remove();
} else if (element.parentNode) {
element.parentNode.removeChild(element);
}
}
var f = addParagraphs();
removeElement(document.getElementById("parent"));
我们从
addParagraphs
返回并存储在
f
中的函数是对其创建上下文的一个
闭包。理论上,即使函数不使用
parentElm
、
child1
或
child2
,它仍然有一个对其创建位置的上下文的引用,而该上下文则引用了这些变量,使其保留在内存中。(现代JavaScript引擎可以对此进行优化。)因此,只要我们有对
f
的引用,那些DOM元素就仍然存在于内存中,并由保持活动的变量所保持活动。如果你释放
f
,它就不一定是一个
泄漏,但记住这点还是很有用的。
当然,你也可以用更少的代码来创建这些元素:
var parentElm = document.createElement('p');
parentElm.id = "parent";
parentElm.innerHTML =
'<p id="child1">Hello</p>' +
'<p id="child2">world</p>';
document.body.appendChild(parentElm);
或者在现代浏览器上:
document.body.insertAdjacentHTML(
'beforeend',
'<p id="parent">' +
'<p id="child1">Hello</p>' +
'<p id="child2">world</p>' +
'</p>'
);
innerHTML
:我从未听说过与innerHTML
相关的内存泄漏问题。恐怕我不知道这个主题的好参考资料。 - T.J. Crowder