什么时候本地未连接的DOM元素会被垃圾收集?

时间:2016-03-10 09:25:04

标签: javascript dom garbage-collection

Javascript中的对象在丢失范围并且不再引用时会收集垃圾。但是,何时元素不再被引用?请参阅以下IIFE

var el = (function() {
  // Generate DOM element, but don't attach it to DOM
  var div = document.createElement('div');
  // Provide interior content
  div.innerHTML = '<span>A</span><span>B</span>';
  // Get reference to first child element in div
  var result = div.firstChild;
  // Blow away all div content
  div.innerHTML = '';
  // Return original first child element
  return result;
})();

我的问题有两个:

  1. 删除div.innerHTML = '';赋值中的内容是否也删除了对其中任何子节点的引用,或者是否在以后的内存中检索垃圾收集过程时这样做了?
  2. 如果div已经附加到DOM而不是在函数退出时超出范围的局部变量,它会有什么不同吗?

1 个答案:

答案 0 :(得分:4)

  

删除div.innerHTML中的内容='';赋值还删除对其中任何子节点的引用

它会删除 div对它们的引用,是的。当然,如果其他内容(例如您的result变量)引用了它们,则该引用仍然存在。分配完成时会发生这种情况,而不是以后。

您可以通过查看div parentNode span来查看result及其子项(双向)之间的引用的一种方法。 {1}}。在div.innerHTML = '';行之前,它将是对div的引用;之后,它将是null

var el = (function() {
  // Generate DOM element, but don't attach it to DOM
  var div = document.createElement('div');
  // Provide interior content
  div.innerHTML = '<span>A</span><span>B</span>';
  // Get reference to first child element in div
  var result = div.firstChild;
  snippet.log("result.parentNode before clearing div: " + result.parentNode);
  // Blow away all div content
  div.innerHTML = '';
  snippet.log("result.parentNode after clearing div: " + result.parentNode);
  // Return original first child element
  return result;
})();
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

  

如果div已经附加到DOM而不是在函数退出时超出范围的局部变量,那么它会有什么不同吗?

如果div附加到文档,div将被文档引用,并且不可回收。但第二个span<span>B</span>)仍然是,因为没有任何东西再引用它。当您清除nextSibling的内容时,即使第一个范围的div引用也会被清除:

var el = (function() {
  // Generate DOM element, but don't attach it to DOM
  var div = document.createElement('div');
  document.body.appendChild(div);
  // Provide interior content
  div.innerHTML = '<span>A</span><span>B</span>';
  // Get reference to first child element in div
  var result = div.firstChild;
  snippet.log("result.nextSibling before clearing div: " + result.nextSibling);
  // Blow away all div content
  div.innerHTML = '';
  snippet.log("result.nextSibling after clearing div: " + result.nextSibling);
  // Return original first child element
  return result;
})();
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>