删除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 ax
和ax = 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的属性,因为该属性不是该子对象的一部分。