删除ax vs ax = undefined

这两者之间是否有实质性的区别?

delete ax; 

VS

 ax = undefined; 

哪里

 a = { x: 'boo' }; 

可以说它们是相等的吗?

(我没有考虑像“V8喜欢不使用delete更好”的东西 )

他们不相同。 主要区别在于设置

 ax = undefined 

意味着a.hasOwnProperty("x")仍然会返回true,因此它仍然会出现在a.hasOwnProperty("x")循环中,而在Object.keys()

 delete ax 

意味着a.hasOwnProperty("x")将返回false

他们是相同的方式是,你不能通过testing来判断一个属性是否存在

 if (ax === undefined) 

如果你想确定一个属性是否存在,你不应该这样做,你应该总是使用它

 // If you want inherited properties if ('x' in a) // If you don't want inherited properties if (a.hasOwnProperty('x')) 

在原型链 (由zzzzBov提到)之后,调用delete将允许它上升到原型链,而将值设置为undefined将不会查找链接原型中的属性http://jsfiddle.net/NEEw4/1/

 var obj = {x: "fromPrototype"}; var extended = Object.create(obj); extended.x = "overriding"; console.log(extended.x); // overriding extended.x = undefined; console.log(extended.x); // undefined delete extended.x; console.log(extended.x); // fromPrototype 

删除inheritance的属性如果您试图删除的属性被inheritance, delete不会影响它。 也就是说, delete只从对象本身删除属性,而不是inheritance的属性。

 var obj = {x: "fromPrototype"}; var extended = Object.create(obj); delete extended.x; console.log(extended.x); // Still fromPrototype 

因此,如果你需要确定一个对象的值是未定义的,当这个属性被inheritance时, delete将不起作用,在这种情况下,你必须设置(覆盖)它为undefined 。 除非检查它的地方将使用hasOwnProperty ,但它可能不是安全的假设检查它将使用hasOwnProperty

解释这个问题:

delete axax = undefined等价吗?

没有。

前者从variables中删除密钥,后者将该密钥的值设置为undefined 。 迭代对象的属性,并使用hasOwnProperty时,这会有所不同。

 a = { x: true }; ax = undefined; a.hasOwnProperty('x'); //true delete ax; a.hasOwnProperty('x'); //false 

另外,当涉及原型链时,这将会产生显着的差异。

 function Foo() { this.x = 'instance'; } Foo.prototype = { x: 'prototype' }; a = new Foo(); console.log(ax); //'instance' ax = undefined; console.log(ax); //undefined delete ax; console.log(ax); //'prototype' 

名字有点混乱。 ax = undefined只是将属性设置为undefined ,但属性仍然存在:

 > var a = {x: 3}; > ax = undefined; > a.constructor.keys(a) ["x"] 

delete实际删除它:

 > var a = {x: 3}; > delete ax; > a.constructor.keys(a) [] 

是的,有一个区别。 如果使用delete ax ,x不再是a的一个属性,但是如果使用ax=undefined那么它是一个属性,但是它的值是未定义的。

这个来自节点的REPL应该说明不同之处。

 > a={ x: 'foo' }; { x: 'foo' } > for (var i in a) { console.log(i); }; x undefined > ax=undefined; undefined > for (var i in a) { console.log(i); }; x undefined > delete ax; true > for (var i in a) { console.log(i); }; undefined 

我相信你可以看到var o1 = {p:undefined};var o2 = {};

在这两种情况下, op都是undefined但是在第一种情况下,这是因为这是价值 ,在第二种情况下是因为没有价值

delete是允许你从o1 (或另一个赋值给p属性的对象)到o2的操作符: delete o1.p;

反向操作是通过简单地赋值给一个值(在这个例子中是undefined ,但可能是别的东西)来实现的o1.p = undefined;

所以 ,他们是不相同的。


delete op;

  • 如果有属性,则从属性中删除属性p

  • 否则别无所求

op = undefined;

  • 添加属性p到对象,如果它还没有,并将其值设置为undefined

  • 如果对象已经拥有它,只需更改属性的值即可


从性能的angular度来看, delete不好的,因为它修改了对象的结构 (就像添加一个新的属性,如果你没有在构造函数中初始化)。

而将值设置为undefined也会释放内容,但不会强制修改结构。

对象只是一个树形表示,也就是说,在内存中,根指向存储该对象的键的各种内存位置。 并且该位置指向存储该密钥的实际值的另一位置,或者存储子密钥的位置或存储数组值的位置。

当你使用delete从对象中删除任何一个键的时候,实际上它删除了这个键和它的父对象之间的连接,并且键的存储位置和它的值被释放以存储另一个信息。

当您尝试通过将未定义的值设置为其值时删除任何键,则只需设置其值,而不是删除该键。 这意味着密钥存储器位置仍然与其父对象链接,并且值如果密钥未定义。

使用undefined而不是使用delete关键字是一个不好的做法,因为它不会释放该键的内存位置。

即使密钥不存在,如果设置为undefined,那么该密钥将被创build为值“undefined”。

例如。 var a = {} ad = undefined; console.log(a); //这将打印{d:undefined}

删除不能与inheritance的属性,因为该属性不是该子对象的一部分。