【问题标题】:Array.splice (+ loops) vs Delete Object[...] vs Object[...] = undefinedArray.splice (+ 循环) vs Delete Object[...] vs Object[...] = undefined
【发布时间】:2016-10-31 09:04:20
【问题描述】:

因此,为了简单起见,我需要删除/替换一堆(10000 多个)对象,我们可以假设该对象包含一个(字符串)唯一“id”。 这些项目通常需要重命名(更改 ID),但不像查找的那么频繁

{ id: 'one' }, { id: 'two' }, ...

如果我将它们放在“关联数组”中(不好的做法),我可以快速访问它们,但需要循环(慢)才能删除(注意:这实际上不起作用,因为 findIndex 只能在正确的情况下正常工作数组,但 for 循环会做同样的事情)

arr = [];
arr['one'] = { id: 'one' };
arr['two'] = { id: 'two' };
arr.splice(arr.findIndex(function(i) { return i.id === 'one'; }), 1);

如果我将它们放在普通数组中,我必须循环(慢)以通过 ID 查找项目,删除也需要循环(慢)(编辑:在我的特定情况下,删除它应该相对较快因为我已经查过它并有参考,但如果我失去参考,显然会更慢)

arr = [{ id: 'one', }, { id: 'two' }];
arr.splice(arr.findIndex(function(i) { return i.id === 'one'; }), 1);

或者,如果我以明显正确的方式存储它们,我可以选择使用 delete 关键字(我一直被告知它很慢并且会破坏优化),或者设置为未定义(这给我留下了存在很多元素 - 内存泄漏?和较慢的循环)

 obj = { one: { id: one }, two: { id: two } };
 delete obj['one'];

...

 obj = { one: { id: one }, two: { id: two } };
 obj['one'] = undefined;

我认为delete object[...] 是最好的选择,但我对其他人的反馈很感兴趣。我应该使用哪个,为什么?

【问题讨论】:

  • delete 也会释放一些内存。
  • 不能使用array.indexOf({ id: 'one' } ...只能匹配同一个对象引用。与{ id: 'one' }=={ id: 'one' }相同为假
  • array为对象时请改名。
  • this answer。并不是说delete很慢,而是对象的整个结构随着内存分配而改变。这就是影响性能的原因。这不是你能解决的问题。
  • @Joshua Davison 删除属性的速度很慢,并且稍后会导致幕后速度变慢。您可能希望使用Map 对象,它为您提供整个API 来设置、删除、清除所有键等。在普通对象中,最好将所需的对象属性设置为undefined :)

标签: javascript arrays node.js ecmascript-6 javascript-objects


【解决方案1】:

这三种方法是有区别的。

Array.splice 移除一个对象,并将此 1 之后的每个元素推回,因此索引不会被剪切。

Delete 尝试删除对象,但可能会失败。这不会释放内存,只会破坏引用。垃圾收集器可以稍后释放相应的内存。

将变量设置为 undefined 几乎标志着垃圾收集器要删除的对象。它不会立即发生,只有当 JavaScript 感觉如此时才会发生。如果您将足够多的变量设置为未定义,那么此方法几乎可以实现与删除对象相同的效果。

将一个变量设置为undefined与删除它是不一样的,如果你使用delete,你可能会遇到错误,当你再次尝试访问该变量时,设置为undefined就不会发生这种情况。

【讨论】:

  • 为什么删除会失败?您提到删除破坏了引用,GC不会像未定义一样拾取它吗?如果我再次尝试使用(设置)变量,删除如何/为什么会导致错误?设置为 undefined 会留下一个损坏的属性(在循环中发现) - 我知道 GC 会在这里清理,但属性名称等不会随着时间的推移而消耗内存吗?
  • @JoshuaDavison “如果属性是自己的不可配置属性,则以严格模式抛出(在非严格模式下返回 false)。在所有其他情况下返回 true。”。它以同样的方式拾取它。如果您尝试使用它,它只会导致错误。如果您删除它,那么它会完全删除该变量。它不会被定义。如果将其设置为未定义,您仍然会有一个未定义的变量(未定义 =/= 未定义)
猜你喜欢
  • 1970-01-01
  • 2016-08-30
  • 2015-08-08
  • 1970-01-01
  • 2016-10-24
  • 1970-01-01
  • 1970-01-01
  • 2016-04-09
  • 2012-06-20
相关资源
最近更新 更多