如何知道使用document.createElement创建的元素是否仍然存在

时间:2015-11-05 00:32:20

标签: javascript garbage-collection phantomjs

我在我的PhantomJS测试中使用document.createElement创建一个锚元素,如下所示:

var mockLink = null;

beforeEach(function() {
  mockLink = document.createElement('a');
});

it('should foo', function() {
  // Use mockLink in some way
});

我想清理afterEach代码中的元素,以便每个测试都有一个新创建的实例。不幸的是,PhantomJS不支持element.remove()Source

afterEach(function() {
  mockLink.remove();  // Error!
});

我想在不添加webpage plugin的情况下执行此操作。

PhantomJS支持

removeChild,但我新创建的元素没有父母:

mockLink.parentElement // undefined
mockLink.parentElement.removeChild(mockLink); // doesn't work
mockLink.parentNode // also undefined

我新创建的链接似乎也不在文档中。

mockLink.href = 'www.google.com';
document.getElementsByTagName('a'); // doesn't contain google.com

所以我无法做到

document.removeChild(mockLink);

mockLink.ownerDocument.contains(mockLink)也会返回false

似乎除mockLink变量之外的任何地方都没有mockLink存储的引用,这意味着如果我想让我mockLink等于null通过垃圾收集释放内存。但是我如何验证这是否有效?如果我将任何其他变量设置为mockLink然后console.log,它仍然会按照定义出来,因为它将是对内存中相同空间的新引用。将变量设置为mockLink时,如何确认null确实被删除?

2 个答案:

答案 0 :(得分:2)

你发现自己是一个难题。

如果通过设置mockLink = null并确保没有对该元素的其他引用来终止对该元素的所有引用,则垃圾收集器应该能够释放该对象。 / p>

但是,您无法验证这一点,因为为了验证该元素不再可用,您必须保留对它的引用,但这样可以防止它首先收集垃圾。因此,这个难题。

这个问题无法直接从Javascript本身进行衡量。

如果你想设计一次性测试以确保内存被回收,那么你可以获取一个内存快照,创建一个存储在数组中的数十万个对象,清除数组,等待一小段时间运行GC,获取另一个内存快照,多次重复相同的进程并验证进程的内存使用量是否不稳定增加,或者研究内存快照以确保这些对象都不会出现在内存占用空间中。

答案 1 :(得分:1)

如果您的javascript环境支持弱引用,那么您可以创建对该节点的弱引用。取决于实施通知机制,例如回调或参考队列,它们可以告诉您何时收集它们。

网络浏览器中的非特权javascript上下文目前不提供此类API。 Node.js,Nashorn和浏览器插件环境都可以。