Javascript中删除操作符的用途是什么?

删除操作符的行为似乎非常复杂,对于它的实际操作有很多误解 。 对我来说,重新分配一些undefined东西会更可靠地做你期望的事情。

我从来没有见过在非示例代码实际使用的Javascript中的关键字,我想知道是否对任何东西特别有用。 delete有任何目的,不能通过重新分配给undefined 它是否在任何着名的图书馆(如jQuery的,道场,骨干等)使用?

删除有任何目的,不能通过重新分配给未定义?

是。 如果你想揭示一个属性从原型或原因, hasOwnProperty ,并for (...in...)不logging该属性作为现有然后delete是适当的。

 var set = {}; set._x = true; alert('_x' in set); // true set._x = undefined; alert('_x' in set); // true delete set._x; alert('_x' in set); // false 

编辑:正如TJ Crowder所解释的:

delete操作符的目的是从一个对象中完全删除一个属性,而将一个属性设置为undefined只是将该属性设置为undefined

这个问题本身就很重要,但是当你使用inheritance的时候也很重要,因为如果O派生自P

 var P = { prop: 42 }; var O = Object.create(P); // P is O's prototype. 

当你检索O.prop ,如果O有一个具有该名称的属性(即使它的值是未定义的),则从O获得prop的值,但是如果O根本没有该属性,则将检索该值从P.prop改为。

 alert(O.prop); // "42" since O doesn't have its own prop, but P does. O.prop = undefined; alert(O.prop); // "undefined" since O has its own prop. delete O.prop; alert(O.prop); // "42" since the delete "unmasked" P.prop. 

正如Mike Samuel在他的回答中所指出的那样,删除最常见的用法之一是将对象视为一个将名称与值相关联的“属性包”。 “这个名字现在映射到一些假的值”和“这个名字根本没有映射”在逻辑上是有区别的。 “删除”达到后者。

这一切都理解得很好。 我想我可能会添加一个关于JScript 1.0到5.0引擎的有趣的历史logging。

在JScript的原始Microsoft实现中,我们使用OLE自动化样式的IDispatch对象来实现expando对象。 IDispatch当然是通过将一个名字与一个“dispatch id”关联起来的,这个id只是一个整数。 为了dynamic调用,首先你要求调度对象给你一个与名字相关的调度ID,然后你说“现在调用与这个ID相关的方法,给定这些参数”。

这一切都很好。 但是IDispatch合同的其中一个要求是从名称到发送ID的映射在对象的整个生命周期内都是稳定的 。 因此,如果有人说“将属性Foo添加到此对象”,那么我们可能会决定该属性Foo与该对象中的调度标识符0x1234关联。 从那一刻起, 每当对象被请求“Foo”的调度标识符时, 即使Foo被删除并且随后再次被添加 ,它也必须返回0x1234 这允许调用者维护自己的名称/ dispid对的快速caching,而不是每次调用时都必须询问对象。

其实际结果是, “删除”不会减轻该实现中对象的内存负担 ! 当你删除一个属性(在原来的实现中),我们必须添加一些标记为已删除的调度标识符的对象,但是我们必须保留关于名称/ id配对的所有信息,以防名称再次出现。 向对象添加大量的属性,然后删除所有这些属性不会缩小内存中的对象。

当然,JScript引擎已经完全重写了(除了我相信parsing器和词法分析器之外),所以我不知道引擎是否还有这个不寻常的怪癖。 这将是有趣的发现。

如果你这样做

  delete Foo.Bar; 

它完全从对象Foo中删除属性Bar

  Foo.Bar = undefined 

只是将Bar属性设置为未定义,并且Foo.Bar仍然存在

您可以检查以下链接的答案我可以将variables设置为undefined或将undefined作为parameter passing? 这以非常详细的方式解释了差异。

概要:

你当然可以给它定义undefined,但是不会删除这个variables。 只有删除object.property操作符才能真正删除东西。

删除实际上是指属性而不是variables。 浏览器可以让你直接删除variables,但这不是一个好主意,并且在ECMAScript第五版的严格模式下不起作用。 如果你想释放一个对某些东西的引用,所以它可以被垃圾收集,通常说variables= null。

其他答案解释了delete关键字背后的动机。 我想补充一点,到2017年为止,浏览器在删除属性和将属性设置为undefined时都会释放内存

考虑这个例子( roughSizeOfObject()来源 ):

 > var obj = {a:42,b:"b"}; roughSizeOfObject(obj) 26 > obj.a = undefined; roughSizeOfObject(obj) 18 > delete obj.a; roughSizeOfObject(obj) 10 > obj.b = undefined; roughSizeOfObject(obj) 8 > delete obj.b; roughSizeOfObject(obj) 0 

该示例来自Chrome 61(64位)控制台(请注意, String中的所有字符均内部编码为16位无符号整数)。

那么,你最终会在你的对象中包含undefined值的元素。 关键不会消失。