我读过一篇关于内存泄漏的文章,其中垃圾收集器逻辑总结为:
- 垃圾收集器建立一个“根”列表。根通常是在代码中保存引用的全局变量。在 JavaScript 中,“window”对象是可以充当根的全局变量的一个示例。窗口对象始终存在,因此垃圾收集器可以认为它及其所有子对象始终存在(即不是垃圾)。
- 所有根都经过检查并标记为活动的(即不是垃圾)。所有的孩子也被递归地检查。从根可以到达的所有东西都不被视为垃圾。
- 所有未标记为活动的内存现在都可以视为垃圾。收集器现在可以释放该内存并将其返回给操作系统。
此外,MDN 声明 DocumentFragment 不是活动DOM 树的一部分。
DocumentFragment 接口表示一个没有父级的最小文档对象。它用作 Document 的轻量级版本,它存储由节点组成的文档结构的一部分,就像标准文档一样。主要区别在于,由于文档片段不是活动文档树结构的一部分,因此对片段所做的更改不会影响文档、导致重排或在进行更改时产生任何性能影响。
一点一点我开始意识到背后的逻辑,但如果有人能对我有所启发,我将不胜感激:),使用下面的示例,并解释原因:
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>