delete a.x vs a.x = undefined
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 delete
better")
Solution 1:
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 in
loop, and in Object.keys()
delete a.x
means that a.hasOwnProperty("x")
will return 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 delete
will 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/
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 Properties If the property you are trying to delete is inherited, delete
will not affect it. That is, delete
only deletes properties from the object itself, not inherited properties.
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, delete
will not work when the property is inherited, you will have to set (override) it to undefined
in 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
Solution 2:
To paraphrase the question:
Are
delete a.x
anda.x = undefined
equivalent?
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 hasOwnProperty
is used.
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'
Solution 3:
If a.x
is a setter function, a.x = undefined
will call the function whereas delete a.x
will not call the function.
Solution 4:
Yes there is a difference.
If you use delete a.x
the x isn't any more a property of a, but if you use a.x=undefined
it is a property but its value is undefined.
Solution 5:
The names are a little confusing. a.x = undefined
just sets the property to undefined
, but the property is still there:
> var a = {x: 3};
> a.x = undefined;
> a.constructor.keys(a)
["x"]
delete
actually deletes it:
> var a = {x: 3};
> delete a.x;
> a.constructor.keys(a)
[]