16

假设我有一个关联数组 Foo,带有键栏和值 xyz。

 console.log(Foo['bar']);

 >> xyz

 delete Foo['bar'];
 console.log Foo['bar'];

 >> undefined

 Foo['bar'] = 'xyz';
 console.log(Foo['bar']);

 >> xyz

 Foo['bar'] = undefined;
 console.log (Foo['bar']);

 >> undefined

我的问题是,两者中哪一个更有效,它们有什么不同吗?是否存在我应该使用其中一个的场景?

谢谢!

结果:

感谢大家帮助并向我展示 jsperf。将其设置为 undefined 似乎(相对)比 delete 快得多,尽管下面指出的所有警告也非常有趣(事实上,我可能会在未来大量使用 delete 以避免将来出现 leftfield 错误)。

4

7 回答 7

7

我没有对这些操作的性能进行基准测试(正如我在评论中提到的,只是在http://www.jsperf.com上创建一个小基准),但我会失去一些关于差异的说法。

您将始终擅长deleteing 属性,将它们设置为undefinednull将让人员和/或代码挂起,这与IN操作员核对。

if( 'bar' in Foo ) { }

如果true您设置Foo.barundefined. 如果你去,它不会delete Foo.bar

于 2012-12-20T23:53:28.150 回答
7

请注意,如果原型链上存在同名属性,则从对象中删除属性将用同名属性之一替换该属性。

将属性设置为 null 或 undefined 只会掩盖它。

于 2012-12-20T23:57:53.213 回答
5

从长远来看,它会产生负面的性能差异,因为b在后者分配给undefined. 例如:

var a = { b : 0 };

a.b = undefined;

a.hasOwnProperty("b");
>>> true

in关键字 (为 true ) 也是如此"b" in a,因此当是较大对象的一部分时,这很可能会阻碍迭代。

于 2012-12-20T23:54:59.803 回答
5
于 2016-12-20T06:50:30.427 回答
5

经过一些实验和研究,我得出结论,至少在我的机器上,使用delete操作符比赋值慢 6 倍undefined。尽管如此,重要的是要记住jAndy 关于原型链和属性存在的说法

如果您想重新执行我的测试,我实例化了一个包含 50,000 个项目的数组。(项目数量无关紧要,只要它大到足以显示两个测试之间的差异。)

let arr = new Array(500000).fill(null).map(() => ({"item": 42}));

然后我计算了将每个对象的 item 属性分配给数组中未定义的时间量与删除数组中每个对象的 item 属性所需的时间量。

console.time("Assignment To Undefined");
arr.forEach(object => object.item = undefined);
console.timeEnd("Assignment To Undefined");

//Reset the array here...

console.time("Deletion");
arr.forEach(object => delete object.item);
console.timeEnd("Deletion");

我的所有结果:

  • 删除:大约 200 - 170 毫秒。
  • 作业:大约 15 - 40 毫秒。
于 2020-01-15T18:32:40.387 回答
4
于 2012-12-20T23:55:09.323 回答
2

由于删除该属性不会以编程方式将其设置为未定义,因此它实际上取决于您想要的编程结果。

delete Foo['bar'];从对象中删除bar属性。Foo如果有人迭代Foo.

Foo['bar'] = undefined将属性设置为未定义,但它仍然存在于对象上并且仍然存在,但值为undefined.

因此,如果您想摆脱该属性,请使用delete. 如果您希望该属性仍然存在,但有一个undefined值,则将其设置为undefined.

如果您真的只是想知道哪个最快并且由于某种原因不关心编程差异,那么请访问 jsperf.com,为自己制作两个比较测试用例,并在一堆不同的浏览器中运行 jsperf你。所有性能问题都应通过相关的真实世界测试来回答。

于 2012-12-21T00:19:19.473 回答