Javascript中删除运算符的用途是什么?

Pet*_*son 61 javascript

删除操作符的行为似乎非常复杂,并且对它实际执行的操作存在许多误解.对我而言,似乎重新分配某些内容undefined会更可靠地完成您的期望.

我从未delete在非实例代码中看到Javascript中实际使用的关键字,我想知道它是否对任何东西特别有用.是否delete有任何通过重新分配无法实现的目的undefined它是否在任何着名的库中使用(例如jQuery,dojo,backbone等)?

Mik*_*uel 67

删除是否有任何无法通过重新分配到未定义的目的?

是.如果你想揭露从原型或事业性质in,hasOwnProperty以及for (...in...)不记录财产作为现有然后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
Run Code Online (Sandbox Code Playgroud)

编辑:正如TJ Crowder所说:

delete运算符的目的是从对象中完全删除属性,而将属性设置为undefined仅将属性设置为undefined.

这本身就很重要,但是当你使用继承时它也很重要,因为如果O来自P

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

当你检索时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.
Run Code Online (Sandbox Code Playgroud)


Eri*_*ert 23

正如Mike Samuel在他的回答中指出的那样,删除最常见的用法之一就是当你将一个对象视为一个将名称与值相关联的"属性包"时."此名称现在映射到某个虚假值"和"此名称根本没有映射"之间存在逻辑上的区别."删除"实现了后者.

这一切都得到了相当好的理解.我想我可能会添加一个有关JScript 1.0到5.0引擎的有趣历史记录.

在那些原始的Microsoft JScript实现中,我们使用OLE Automation风格的IDispatch对象来实现expando对象.IDispatch当然通过将名称与"dispatch id"相关联来实现,"dispatch id"只是一个整数.要动态调用,首先要求dispatch对象为您提供与名称关联的调度ID,然后您说"现在调用与此ID关联的方法,给定这些参数".

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

实际的结果是"删除"不会以任何方式减轻该实现中对象的内存负担!当您删除属性时(在原始实现中),我们必须在对象上添加一个位,标记将调度标识符标识为已删除,但是如果该名称返回,我们必须保留有关名称/ id配对的所有信息.向对象添加大量属性然后删除所有属性不会缩小内存中的对象.

JScript引擎当然已经完全重写了我的时间(除了,我相信,解析器和词法分析器)所以我不知道引擎是否还有这个不寻常的怪癖.找出答案会很有趣.


par*_*mar 11

如果你这样做

 delete Foo.Bar;
Run Code Online (Sandbox Code Playgroud)

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

 Foo.Bar = undefined
Run Code Online (Sandbox Code Playgroud)

仅将Bar属性设置为undefined且Foo.Bar仍然存在