[英]add/remove listeners on javascript ( garbage collector )
关于添加/删除DOM对象的侦听器,我有一个简单的问题。 我想问一下,当从页面中删除元素时,垃圾收集器是否能够收集内存。
恩。 带有几个孩子列表的<ul>
标签( <li>
)
var ul = document.getElementById('someParent');
var children = ul.children;
var someFunction = function() {};
for(var i = 0; i < children.length; i++) {
children[i].addEventListener('click', someFunction);
}
// This is where I am not sure, would the garbage collector be able to collect
// the memory allocated on adding listener on children,
// if I remove the ul tag?
ul.remove();
行ul.remove();
将从DOM中删除ul
元素及其所有子元素。 但只要您引用了那些侦听器, li
元素和ul
元素,就不会释放事件侦听器的内存。 您在变量children
, someFunction
和ul
有哪些。
如果你想让垃圾收集器清理所有这些,你可以这样做:
ul.remove();
children = null;
someFunction = null;
ul = null;
这样变量children
就不会保存对这些元素的引用,如果你的代码中没有任何其他变量来保存这些元素的引用,垃圾收集器就会收集它们。 someFunction
也是someFunction
。 请注意, ul
元素包含对其子项和侦听器的所有引用,因此也必须清除ul
。
完全没有,您可以在其他地方访问ul变量。 下面的例子显示了这一点。
var ul = document.getElementById('someParent');
ul.remove();
console.log(ul); // ul and all li tags
document.body.appendChild(ul); // ul appears again
该示例不是正常情况。 通常情况下,您希望在“按钮单击”事件中访问DOM引用。 只要事件不是解除绑定,该引用将始终可用。 例如:
var ul = document.getElementById('someParent');
var myButton = document.getElementById('myButton');
myButton.addEventListener('click', function () {
ul.innerHTML += '<li>Some text</li>'
});
ul.remove();
myButton.click(); // no exception when execting button click event
为了避免JS中的内存泄漏:
所以您可以稍微修改一下您的活动。
myButton.addEventListener('click', function () {
// check ul belongs to visible DOM
if (!document.body.contains(ul)) {
ul = null;
return;
}
ul.innerHTML += '<li>Some text</li>'
});
如果有人可以为我确认这一点,我会很感激。
根据我的理解, 是的 ,它将被垃圾收集。 根据MDN内存管理
垃圾收集算法所依赖的主要概念是参考概念。 在内存管理的上下文中,如果前者可以访问后者(隐式或显式),则称该对象引用另一个对象。 例如,JavaScript对象具有对其原型(隐式引用)及其属性值(显式引用)的引用。
基本上如果DOM无法找到对所述元素的引用,它将在不久的将来垃圾收集它。 查看.remove()如何工作的DOM标准规范,它将运行一系列步骤,设置父项和兄弟项的新索引,删除对该元素的所有引用。
因为没有对所述元素的引用,所以它将被垃圾收集。 在您的示例中,您只将eventListeners添加到您创建的特定<ul>
元素的子元素中。 当你删除一个元素时,你也删除了它的子元素的所有引用(我认为这在上面链接的步骤中更清楚,它们实际上将父索引设置为指向它自己)。
编辑:@ contrabit是正确的。 我没有看到你把children
存放在变量中。 只要它们是对它们的引用,它们就不会被垃圾收集。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.