Javascript dom操纵内存泄漏

时间:2015-12-07 08:07:45

标签: javascript jquery html dom memory-leaks

您好我使用原始javascript DOM创建了一个dom:

Javascript代码:

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"; // Is it a good way 

parentElm.appendChild(child1);
parentElm.appendChild(child2);
document.body.appendChild(parentElm);

生成的HTML是:

<div id="parent">
    <p id="child1">Hello</p>
    <p id="child2">World</p>
</div>

现在,当我想删除上述部分时,我会按照以下步骤进行操作。

document.body.removeChild(parentElm);

这里我害怕javascript内存泄漏。

  • 如果我从正文中删除父元素,它是否完全删除 从记忆里。 ?
  • 如果我从正文中删除父元素,那么它是 垃圾收集器也会自动从内存中删除子元素。或者我需要删除 手动的子元素?
  • 在上面的代码中使用innerHTML是一个好方法(child1.innerHTML =“Hello”;)

请帮助我进行javascript dom操作。

1 个答案:

答案 0 :(得分:6)

  

如果我从正文中删除父元素,它是否完全从内存中删除。 ?

如果,您的parentElmchild1child2变量不再在范围内,或者您已将它们设置为其他值,是的。

  

如果我从body中删除父元素,它的子元素是否也会被垃圾收集器自动从内存中删除。或者我需要手动删除子元素?

如果您的child1child2变量不在范围内,或者您已将它们设置为其他值,是的,删除父级就是删除子级所需的全部内容让它们得到清理。

  

在上面的代码中使用innerHTML是一个好方法(child1.innerHTML =&#34; Hello&#34 ;;)

这很好,也很常见。

所以这里没有内存泄漏,例如:

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"; // Is it a good way 

    parentElm.appendChild(child1);
    parentElm.appendChild(child2);
    document.body.appendChild(parentElm);
}

function removeElement(element) {
    if (element.remove) {
        element.remove(); // newer DOM method, not on all browsers
    } 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"; // Is it a good way 

    parentElm.appendChild(child1);
    parentElm.appendChild(child2);
    document.body.appendChild(parentElm);

    return function() {
        console.log("Hi there");
    };
}

function removeElement(element) {
    if (element.remove) {
        element.remove(); // newer DOM method, not on all browsers
    } else if (element.parentNode) {
        element.parentNode.removeChild(element);
    }
}

var f = addParagraphs();
removeElement(document.getElementById("parent"));

我们从addParagraphs返回并存储在f中的函数是在其创建的上下文中的闭包。理论上,即使函数没有&#39; t使用parentElmchild1child2,它引用了创建它的上下文,并且该上下文引用了这些变量,并将它们保存在内存中。 (现代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>'
);