gpt4 book ai didi

javascript - 垃圾回收和 DocumentFragment

转载 作者:行者123 更新时间:2023-11-29 20:51:07 24 4
gpt4 key购买 nike

我看过一篇关于内存泄漏的文章,其中垃圾收集器逻辑被总结为:

  1. The garbage collector builds a list of "roots". Roots usually are global variables to which a reference is kept in code. In JavaScript, the "window" object is an example of a global variable that can act as a root. The window object is always present, so the garbage collector can consider it and all of its children to be always present (i.e. not garbage).
  2. All roots are inspected and marked as active (i.e. not garbage). All children are inspected recursively as well. Everything that can be reached from a root is not considered garbage.
  3. All pieces of memory not marked as active can now be considered garbage. The collector can now free that memory and return it to the OS.

此外,MDN 指出 DocumentFragment 不是事件 DOM 树的一部分。

The DocumentFragment interface represents a minimal document object that has no parent. It is used as a lightweight version of Document that stores a segment of a document structure comprised of nodes just like a standard document. The key difference is that because the document fragment isn't part of the active document tree structure, changes made to the fragment don't affect the document, cause reflow, or incur any performance impact that can occur when changes are made.

我一点一点地开始意识到背后的逻辑,但如果有人能对我有所启发,我将不胜感激:),使用下面的示例,并解释原因:

1. 它是被认为是在使用 DOM 引用后使其无效的良好做法。
2. 是否需要取消对 DocumentFragment 和包含它的元素的引用。

function usefulFunction() {
let existingNode = document.querySelector(`.existing`)

let createdNode = document.createElement(`ul`)
let fragment = document.createDocumentFragment();
let browsers = ['Firefox', 'Chrome', 'Opera',
'Safari', 'Internet Explorer'];

browsers.forEach(function(browser) {
var li = document.createElement('li');
li.textContent = browser;
fragment.appendChild(li);
});

existingNode.appendChild(createdNode)
createdNode.appendChild(fragment)

fragment = null
createdNode = null
existingNode = null
}

usefulFunction()
<div class="existing"></div>

更新的代码段

let existingNode

function helperFunction(object) {
let createdNode = document.createElement(`div`)
createdNode.innerHTML = `Hello, I am a beautiful div`

existingNode.appendChild(createdNode)
existingNode = null
}

function usefulFunction() {
existingNode = document.querySelector(`.existing`)
let fragment = document.createDocumentFragment();
let browsers = ['Firefox', 'Chrome', 'Opera',
'Safari', 'Internet Explorer'];

browsers.forEach(function(browser) {
var li = document.createElement('li');
li.textContent = browser;
fragment.appendChild(li);
});

existingNode.appendChild(fragment)
helperFunction()
}


usefulFunction()
<div class="existing"></div>

最佳答案

如果您正确使用局部变量,通常在使用它们之后几乎不需要将它们置为无效。当您离开函数的范围时,变量就会消失,并且它们引用的任何对象不是来自仍在范围内的某个变量的引用将成为垃圾。文档片段不从 DOM 引用,仅从变量引用,因此当变量被销毁时,可以对片段进行垃圾回收。

这是您应该谨慎使用全局变量的原因之一。它们应该只用于需要随时间持续存在的数据,例如保持应用程序的状态。

请注意,在您的第一个示例代码中,使变量无效对垃圾回收没有影响,因为它们包含的所有节点和片段都附加到 DOM。但如果不是,这些对象将在函数结束后立即变成垃圾,因此无需在返回前使变量无效。

在第二个片段中,如果您从 DOM 中删除该元素,则应使 existingNode 无效。否则,全局变量将阻止节点被垃圾收集。但是,如果希望节点在应用程序的整个生命周期内保持不变,则无需担心变量。

关于javascript - 垃圾回收和 DocumentFragment,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51831580/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com