Javascript 删除 ax vs ax = 未定义

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14967535/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 18:29:52  来源:igfitidea点击:

delete a.x vs a.x = undefined

javascript

提问by bevacqua

Is there any substantial difference in doing either of these?

做这两个有什么实质性的区别吗?

delete a.x;

vs

对比

a.x = undefined;

where

在哪里

a = {
    x: 'boo'
};

could it be said that they are equivalent?

可以说它们是等价的吗?

(I'm not taking into account stuff like "V8 likes not using deletebetter")

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

回答by Juan Mendes

They are not equivalent. The main difference is that setting

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

a.x = undefined

means that a.hasOwnProperty("x")will still return true, and therefore, it will still show up in a for inloop, and in Object.keys()

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

delete a.x

means that a.hasOwnProperty("x")will return false

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

The way that they are the same is that you can't tell if a property exists by testing

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

if (a.x === undefined)

Which you shouldn't do if you are trying to determine if a property exists, you should always use

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

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

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

Following the prototype chain(mentioned by zzzzBov) Calling deletewill allow it to go up the prototype chain, whereas setting the value to undefined will not look for the property in the chained prototypes http://jsfiddle.net/NEEw4/1/

跟随原型链(由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

Deleting Inherited PropertiesIf the property you are trying to delete is inherited, deletewill not affect it. That is, deleteonly deletes properties from the object itself, not inherited properties.

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

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

Therefore, if you need to make sure an object's value will be undefined, deletewill not work when the property is inherited, you will have to set (override) it to undefinedin that case. Unless the place that is checking for it will use hasOwnProperty, but it likely wouldn't be safe to assume that everywhere that checks it will use hasOwnProperty

因此,如果您需要确保对象的值未定义,delete并且在继承属性时不起作用,则undefined在这种情况下您必须设置(覆盖)它。除非检查它的地方会使用hasOwnProperty,但假设检查它的所有地方都会使用它可能是不安全的hasOwnProperty

回答by zzzzBov

To paraphrase the question:

解释一下这个问题:

Are delete a.xand a.x = undefinedequivalent?

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

No.

不。

The former removes the key from the variable, the later sets the key with a value of undefined. This makes a difference when iterating over properties of objects, and when hasOwnPropertyis used.

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

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

Additionally, this will make a significant difference when the prototype chain is involved.

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

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'

回答by martin770

If a.xis a setter function, a.x = undefinedwill call the function whereas delete a.xwill not call the function.

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

回答by Blender

The names are a little confusing. a.x = undefinedjust sets the property to undefined, but the property is still there:

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

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

deleteactually deletes it:

delete实际上删除它:

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

回答by Blender

Yes there is a difference. If you use delete a.xthe x isn't any more a property of a, but if you use a.x=undefinedit is a property but its value is undefined.

是,有一点不同。如果你使用delete a.xx 不再是 a 的一个属性,但如果你使用a.x=undefined它是一个属性但它的值是未定义的。

回答by xavierm02

I'm sure you can see the difference between var o1 = {p:undefined};and var o2 = {};.

我敢肯定,你可以看到之间的差异var o1 = {p:undefined};var o2 = {};

In both cases, o.pwill be undefinedbut in the first case, it's because that's the valueand in the second case because there is no value.

在这两种情况下,o.p将是undefined但在第一种情况下,这是因为这是value而在第二种情况下因为没有 value

deleteis the operator that lets you get from o1(or another object that has a value assigned to its pproperty) to o2that way: delete o1.p;.

delete是允许您从o1(或另一个具有分配给其p属性的值的对象)到o2这种方式的运算符:delete o1.p;

The reverse operation is made by simply assigning a value (undefinedin this example but it could be something else) to the property o1.p = undefined;.

反向操作是通过简单地undefined为 property分配一个值(在这个例子中,但它可以是其他东西)来完成的o1.p = undefined;

So no, they are not equivalent.

所以,它们不是等价的。



delete o.p;will

delete o.p;将要

  • remove the property pfrom the object if it has one

  • do nothing otherwise

  • p如果对象有一个属性,则从对象中删除该属性

  • 别的什么都不做

o.p = undefined;will

o.p = undefined;将要

  • add a property pto the object if it doesn't have one yet and set its value to undefined

  • simply change the value of the property if the object already has it

  • p如果对象还没有属性,则向该对象添加一个属性并将其值设置为undefined

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



From a performance perspective, deleteis badbecause it modifies the structure of the object(just like adding a new property if you haven't initialized it in the constructor).

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

Whereas setting the value to undefinedreleases the content as well but without forcing to modify the structure.

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

回答by Laxmikant Dange

Object is simply a tree representation, that means, in memory the root points to various memory locations where keys of that object are stored. and that location points to another location where the actual value of that key is stored, or locations where the child keys are stored or locations where the array values are stored.

对象只是一个树表示,这意味着,在内存中,根指向存储该对象键的各种内存位置。并且该位置指向存储该键的实际值的另一个位置,或存储子键的位置或存储数组值的位置。

When you delete any key from an object using delete, actually it deletes link between that key and its parent object and the memory locations of key and its value are freed up to store another information.

当您使用 delete 从对象中删除任何键时,实际上它会删除该键与其父对象之间的链接,并且键的内存位置及其值被释放以存储其他信息。

When you try to delete any key by setting undefined as its value, then you are just setting its value, not deleting that key. That means that keys memory location is still linked with its parent object and the value if key is undefined.

当您尝试通过将 undefined 设置为其值来删除任何键时,您只是在设置其值,而不是删除该键。这意味着键的内存位置仍然与其父对象以及键未定义时的值相关联。

Using undefined instead of using delete keyword is a bad practice, as it doesn't release memory location of that key.

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

Even if the key is not present, and you set it as undefined, then that key will get created with value undefined.

即使该键不存在,并且您将其设置为 undefined,那么该键也将使用 value 创建undefined

e.g.

例如

var a = {};
a.d = undefined;
console.log(a); // this will print { d: undefined }

delete can't be worked with inherited properties because that property is not the part of that child object.

delete 不能与继承的属性一起使用,因为该属性不是该子对象的一部分。

回答by kojiro

This REPL from node should illustrate the difference.

来自节点的这个 REPL 应该说明差异。

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

回答by Lonnie Best

Using an array, instead of an object, I can showcase that delete uses less heap memory than undefined.

使用数组而不是对象,我可以展示 delete 使用的堆内存比 undefined 少。

For example, this code will not finish:

例如,这段代码不会完成:

let y = 1;
let ary = [];
console.log("Fatal Error Coming Soon");
while (y < 4294967295)
{
    ary.push(y);
    ary[y] = undefined;
    y += 1;
}
console(ary.length);

It produces this error:

它产生这个错误:

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory.

So, as you can see undefinedactually takes up heap memory.

所以,正如你所看到的,undefined实际上占用了堆内存。

However, if you also deletethe ary-item (instead of just setting it to undefined), the code will slowly finish:

但是,如果您还delete使用 ary-item(而不是将其设置为undefined),则代码将慢慢完成:

let x = 1;
let ary = [];
console.log("This will take a while, but it will eventually finish successfully.");
while (x < 4294967295)
{
    ary.push(x);
    ary[x] = undefined;
    delete ary[x];
    x += 1;
}
console.log(`Success, array-length: ${ary.length}.`);

These are extreme examples, but they make a point about deletethat I haven't seen anyone mention anywhere.

这些都是极端的例子,但它们delete说明了我在任何地方都没有看到任何人提到的问题。