删除 ax vs ax = undefined

新手上路,请多包涵

做这些中的任何一个有什么实质性的区别吗?

 delete a.x;

对比

a.x = undefined;

在哪里

a = {
    x: 'boo'
};

能说它们是等价的吗?

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

原文由 bevacqua 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 312
2 个回答

它们不等价。主要区别在于设置

a.x = undefined

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

delete a.x

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

您无法通过测试判断属性是否存在

if (a.x === undefined)

如果你试图确定一个属性是否存在,你应该总是使用

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

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

跟随原型链(由 zzzzBov 提到)调用 delete 将允许它上升到原型链,而将值设置为 undefined 将不会在链接的原型中查找属性

 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

删除继承属性 如果您尝试删除的属性是继承的, delete 不会影响它。也就是说, delete 只删除对象本身的属性,而不是继承的属性。

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

因此,如果您需要确保对象的值未定义, delete 在属性被继承时将不起作用,您必须将其设置(覆盖)为 undefined 案子。除非检查它的地方将使用 hasOwnProperty ,但假设检查它的所有地方都将使用 hasOwnProperty 可能是不安全的

原文由 Ruan Mendes 发布,翻译遵循 CC BY-SA 4.0 许可协议

解释一下这个问题:

delete a.xa.x = undefined 等价吗?

不。

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

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

此外,当涉及原型链时,这将产生重大差异。

 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'

原文由 zzzzBov 发布,翻译遵循 CC BY-SA 4.0 许可协议

推荐问题