什么时候应该在 JavaScript 中使用 delete 和将元素设置为 null?

IT技术 javascript garbage-collection
2021-02-27 23:52:29

可能的重复:
在 JavaScript 中删除对象

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

3个回答

在 JavaScript 中没有强制垃圾回收的方法,您也不需要这样做。x.y = null;并且delete x.y;都消除了x对 的前一个值的引用y必要时,该值将被垃圾收集。

如果您将一个属性设为 null,它仍被视为对象上的“设置”并将被枚举。 我能想到的唯一一次你更喜欢的地方delete是,如果你要枚举x.

考虑以下:

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
@pqsk 你提到的 for 循环是变量提升的一个实例。一旦你把头包起来,它实际上很酷!jsfiddle.net/a4awzxd7/1
2021-04-29 23:52:29
@catalyst294 好吧,你可以说它很酷,但这也是周围有这么多乱七八糟的 javascript 代码的主要原因。如果编写代码的人不完全理解缺乏作用域,这也可能导致意外行为。
2021-04-30 23:52:29
JavaScript 是一种如此奇特的语言。我觉得奇怪的一件事是 for 循环中的变量如何在循环后不超出范围。在您的代码中,您不需要重新定义“key”,因为“key”已经定义。我告诉你很奇怪。完全控制是令人沮丧的。实际上,我以前从未听说过这个 delete 关键字。我总是将变量归零,因为我可能不小心在其他地方定义了它,而且我不知道解析器是什么(或使用 IE 的用户!)。感谢您分享您的知识。
2021-05-15 23:52:29

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

两者之间可观察到的主要区别在于,如果您使用 for..in 循环遍历键,删除键会导致迭代看到的条目更少。

我建议一般情况下更喜欢删除,除非您要重复设置和清除相同的键,这会导致保留散列表结构。然而,在任何典型情况下,这两种技术之间的任何性能差异都将是不可估量的。

-m@

在 JavaScript 中无法在特定时间强制进行垃圾回收。每个 JavaScript 引擎都有自己的处理方式。

但是,您可以做的是确保您的对象没有在任何地方被引用。将它们设置为 null 或删除它们实际上是在做同样的事情(删除永远不会删除对象——它只会删除对它的引用)。当垃圾收集确实运行时,它会检查是否存在对给定对象的任何引用 - 如果没有,它将从内存中删除它。这是发生内存泄漏的地方(JavaScript 对象正在引用 DOM 对象,反之亦然)。

确保删除所有引用,你会没事的。

@NoBugs 我认为这就是他的意思。“他们自己的处理方式” === “一种变体”...
2021-04-30 23:52:29
“每个 JavaScript 引擎都有自己的处理方式” - 不完全准确,根据这一点,自 2012 年以来,所有现代浏览器都使用“标记和扫描”算法的变体:developer.mozilla.org/en-US/文档/网络/JavaScript/...
2021-05-02 23:52:29