删除ax与ax =未定义

bev*_*qua 125 javascript

做其中任何一项都有什么实质性的区别吗?

delete a.x;
Run Code Online (Sandbox Code Playgroud)

VS

a.x = undefined;
Run Code Online (Sandbox Code Playgroud)

哪里

a = {
    x: 'boo'
};
Run Code Online (Sandbox Code Playgroud)

可以说它们是等价的吗?

(我没有考虑像"V8喜欢不用delete得更好"之类的东西)

Jua*_*des 163

他们并不等同.主要区别在于设定

a.x = undefined
Run Code Online (Sandbox Code Playgroud)

意味着它a.hasOwnProperty("x")仍然会返回true,因此,它仍将显示在for in循环中,并且在Object.keys()

delete a.x
Run Code Online (Sandbox Code Playgroud)

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

它们相同的方式是您无法通过测试来判断属性是否存在

if (a.x === undefined)
Run Code Online (Sandbox Code Playgroud)

如果您要确定某个属性是否存在,则不应该这样做,您应该始终使用

// If you want inherited properties
if ('x' in a)

// If you don't want inherited properties
if (a.hasOwnProperty('x'))
Run Code Online (Sandbox Code Playgroud)

在原型链之后(由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
Run Code Online (Sandbox Code Playgroud)

删除继承的属性如果要继承的属性是继承的,delete则不会影响它.也就是说,delete只删除对象本身的属性,而不是继承的属性.

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

因此,如果您需要确保对象的值将是未定义的,delete则在继承该属性时将无法工作,undefined在这种情况下您将必须设置(覆盖)它.除非检查它的地方将使用hasOwnProperty,但可能不安全地假设在任何检查它将使用hasOwnProperty


zzz*_*Bov 32

解释一下这个问题:

delete a.xa.x = undefined相同呢?

没有.

前者从变量中删除键,后者使用值设置键undefined.当迭代对象的属性以及何时hasOwnProperty使用时,这会产生差异.

a = {
    x: true
};
a.x = undefined;
a.hasOwnProperty('x'); //true
delete a.x;
a.hasOwnProperty('x'); //false
Run Code Online (Sandbox Code Playgroud)

此外,当涉及原型链时,这将产生显着差异.

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

a.x = undefined;
console.log(a.x); //undefined

delete a.x;
console.log(a.x); //'prototype'
Run Code Online (Sandbox Code Playgroud)

  • +1关于`删除`的优点,允许它上升到原型链 (2认同)

mar*_*770 5

如果a.x是 setter 函数,a.x = undefined将调用该函数delete a.x而不调用该函数。