bevacqua
bevacqua

Reputation: 48476

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

Upvotes: 207

Views: 34848

Answers (9)

Ruan Mendes
Ruan Mendes

Reputation: 92274

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(). Whereas

delete a.x

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

You can't tell if a property exists by testing

if (a.x === undefined)

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

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

Upvotes: 243

Lonnie Best
Lonnie Best

Reputation: 11364

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.

Upvotes: 4

martin770
martin770

Reputation: 1288

If a.x is a setter function, a.x = undefined will call the function whereas delete a.x will not call the function.

Upvotes: 8

Laxmikant Dange
Laxmikant Dange

Reputation: 7688

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.

Upvotes: 1

xavierm02
xavierm02

Reputation: 8767

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.

Upvotes: 1

user2015944
user2015944

Reputation:

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.

Upvotes: 3

zzzzBov
zzzzBov

Reputation: 179046

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'

Upvotes: 38

Blender
Blender

Reputation: 298146

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

Upvotes: 2

kojiro
kojiro

Reputation: 77089

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

Upvotes: 1

Related Questions