This page looks best with JavaScript enabled

Nullify prop value vs deleting key in an object

 ·   ·  ☕ 3 min read

It is common advise to nullify a prop value within an object rather than deleting the prop. Should you prefer one over the other? Especially, in performance intensive applications.

Delete object prop

What do you do when you do not need a key-value pair in an object? Why, we simply delete it, of course.

1
2
3
4
5
6
7
8
9
const earth = { name: "earth", position: 3, life: true };

console.log(earth);
// { name: 'earth', position: 3, life: true }

delete earth["life"];

console.log(earth);
// { name: 'earth', position: 3 }

This is clean and just works.

Except that the compiler/interpreter has to do so much extra work to delete a prop within an object. When the object changes, Javascript will recompile “associated” code internal to the compiler and reset things are required. This requires more computation and time - especially if you have large number of elements.

At least, in theory.

What you can do instead - null the prop

You can set key value to undefined or null in the object.

1
2
3
4
5
6
7
8
9
const earth = { name: "earth", position: 3, life: true };

console.log(earth);
// { name: 'earth', position: 3, life: true }

earth["life"] = null;

console.log(earth);
// { name: 'earth', position: 3, life: null }

I often use undefined instead of null since I can expect props to be actual nulls at one time or the other.

A Quick Test

Consider below code that deletes or nullifies prop value for a 1000 elements in an object.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
const arr = new Array(1e5).fill("hello");
const obj = { ...arr };

console.time("del");
Object.entries(obj).forEach(ele => delete obj[ele]);
console.timeEnd("del");

console.time("null");
Object.entries(obj).forEach(ele => (obj[ele] = null));
console.timeEnd("null");

/*
del: 184.942ms
null: 221.430ms

del: 200.653ms
null: 229.400ms

del: 199.422ms
null: 268.564ms
*/

The quick and dirty test does not reveal anything significant in a set of elements in a loop - but surprisingly delete is better than nullifying a prop value.

Let us transfer the time measurement to the individual transactions rather than the entire loop. We will take an average of all observed times to output average performance.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
const { performance } = require("perf_hooks");

const arr = new Array(1000).fill("hello");
const obj = { ...arr };

const delTimes = [];
const nullTimes = [];

let start;
Object.entries(obj).forEach(ele => {
  start = performance.now();
  delete obj[ele];
  delTimes.push(performance.now() - start);
});

console.log(
  "del avg: ",
  delTimes.reduce((sum, val) => (sum += val)) / delTimes.length
);

Object.entries(obj).forEach(ele => {
  start = performance.now();
  obj[ele] = null;
  nullTimes.push(performance.now() - start);
});

console.log(
  "null avg: ",
  nullTimes.reduce((sum, val) => (sum += val)) / nullTimes.length
);

/*
del avg:  0.015970081090927124
null avg:  0.014829903841018677

del avg:  0.009639912843704223
null avg:  0.01293981671333313

del avg:  0.012559592723846436
null avg:  0.006950092315673828

*/

‘delete` still has an upper hand - but nothing “significant”.

If we increase the array size to 1e5 -

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
/*
del avg:  0.0019049220073223115
null avg:  0.0018892455852031708

del avg:  0.0019672254502773284
null avg:  0.0022597119933366774

del avg:  0.0024934078419208525
null avg:  0.0036383388513326646
*/

Nope - not quite what I expected. But, here we are.

Conclusion

I will continue using delete until the time I understand the concepts much better than what I do now.

Stay in touch!
Share on

Prashanth Krishnamurthy
WRITTEN BY
Prashanth Krishnamurthy
Technologist | Creator of Things