delete a.x vs a.x = undefined

Javascript

Javascript Problem Overview


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")

Javascript Solutions


Solution 1 - Javascript

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 - Javascript

To paraphrase the question:

> Are delete a.x and a.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 - Javascript

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 - Javascript

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)
[]

Solution 5 - Javascript

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 6 - Javascript

Using an array, instead of an object, I can showcase that delete uses less heap memory than 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 undefined actually takes up heap memory.

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

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 delete that I haven't seen anyone mention anywhere.

Solution 7 - Javascript

This REPL from node should illustrate the difference.

> 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

Solution 8 - Javascript

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

In both cases, o.p will be undefined but in the first case, it's because that's the value and in the second case because there is no value.

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

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

So no, they are not equivalent.


delete o.p; will

  • remove the property p from the object if it has one

  • do nothing otherwise

o.p = undefined; will

  • add a property p to 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


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

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

Solution 9 - Javascript

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.

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.

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

Even if the key is not present, and you set it as undefined, then that key will get created with 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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionbevacquaView Question on Stackoverflow
Solution 1 - JavascriptJuan MendesView Answer on Stackoverflow
Solution 2 - JavascriptzzzzBovView Answer on Stackoverflow
Solution 3 - Javascriptmartin770View Answer on Stackoverflow
Solution 4 - JavascriptBlenderView Answer on Stackoverflow
Solution 5 - Javascriptuser2015944View Answer on Stackoverflow
Solution 6 - JavascriptLonnie BestView Answer on Stackoverflow
Solution 7 - JavascriptkojiroView Answer on Stackoverflow
Solution 8 - Javascriptxavierm02View Answer on Stackoverflow
Solution 9 - JavascriptLaxmikant DangeView Answer on Stackoverflow