何时应该在JavaScript中使用delete而不是将元素设置为null?

74

可能有重复:
JavaScript中删除对象

我有一个JS对象,它有大量的属性。如果我想强制浏览器垃圾回收这个对象,我需要将这些属性都设置为null吗?还是我需要使用delete运算符?两者之间有什么区别?


4
请参考以下链接以了解如何在 JavaScript 中删除对象和取消设置变量:
  • 查看 https://dev59.com/aXRB5IYBdhLWcg3wCjcV
  • 查看 https://dev59.com/jXI-5IYBdhLWcg3w9tdw
- Crescent Fresh
@jeffreyveon:答案可以在Crescent Fresh链接的第一个问题的回复中找到,但在您阅读之前,我将在此进行总结:您无法“强制”浏览器垃圾回收任何内容;delete仅从对象中删除属性(而不是将属性的值设置为null)。假设您没有对对象的外部引用,则无论您首先是否清空或删除属性,它都将被垃圾回收。 - Shog9
3个回答

160

在JavaScript中,没有办法强制进行垃圾回收,而且你实际上也不需要这样做。 x.y = null;delete x.y; 都会消除xy之前值的引用。当必要时,该值将被垃圾回收。

如果你将属性设置为null,它仍然被视为对象上“已设置(set)”的属性,因此会被枚举(enumerate)。 我唯一能想到的情况是,如果你要枚举x的属性,那么你可能更喜欢使用delete

考虑以下示例:

var foo = { 'a': 1, 'b': 2, 'c': 3 };

console.log('Deleted a.');
delete foo.a
for (var key in foo)
  console.log(key + ': ' + foo[key]);

console.log('Nulled out b.');
foo['b'] = null;
for (var key in foo)
  console.log(key + ': ' + foo[key]);

这段代码将会产生以下输出:

Deleted a.
b: 2
c: 3
Nulled out b.
b: null
c: 3

1
JavaScript是一种特别的语言。我发现有些奇怪的地方就是在for循环中的变量很特别,它们并没有在循环后失去作用域。在你的代码中,你不需要重新定义"key",因为"key"已经被定义了。这非常奇怪。这让人感到很无奈。事实上,我以前从未听说过delete关键字。我通常会将变量设置为空,以防我在其他地方意外定义了它,而我又不知道解析器(或者使用IE的用户)会怎么做!感谢您分享您的知识。 - pqsk
1
@pqsk,你提到的for循环是变量提升的一个实例。一旦你理解了它,它其实非常酷!http://jsfiddle.net/a4awzxd7/1/ - catalyst294
1
@catalyst294 嗯,你可以说它很酷,但这也是为什么有那么多混乱的Javascript代码存在的主要原因。这也可能会导致意外行为,如果编写代码的人不完全理解缺乏范围的情况。 - awe

24

Javascript对象属性通常使用哈希表实现。将其设置为null会使哈希表中的键指向null值,而delete操作会同时删除键和值。

两者之间的主要区别在于,如果使用for..in循环迭代键,删除键将导致迭代看到的条目数量减少。

一般建议使用删除操作,除非您将反复设置和清除相同的键,这会导致哈希表结构保持不变。但是,在任何典型情况下,使用这两种技术之间的性能差异都无法衡量。

-m@


2
在JavaScript中,没有办法在特定时间强制进行垃圾回收。每个JavaScript引擎都有自己处理垃圾回收的方式。
但是,您可以确保您的对象没有被引用到任何地方。将它们设置为null或删除它们实际上是在做同样的事情(delete从不删除对象-它只是删除对它的引用)。当垃圾回收运行时,它会检查是否有任何对给定对象的引用,如果没有,则将其从内存中删除。这就是内存泄漏发生的地方(JavaScript对象引用DOM对象,反之亦然)。
确保您删除所有引用,您就会没问题了。

每个JavaScript引擎都有自己处理这个的方式-根据此,所有现代浏览器使用“标记和清除”算法的变体,自2012年以来:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management。 - NoBugs
@NoBugs 我认为这就是他的意思。“自己处理的方式”===“变体”。 - dudewad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接