Ways to Empty an Array in JavaScript and the Consequences

As it is famously quoted,

The only way you can stay on top is to remember to touch bottom and get back to basics.

Here is one topic from JavaScript's basic concepts. It is about, Ways to Empty an Array. But wait, is that all? No, there is more to it,

  • Why are we even discussing it here?
  • There seems to be multiple ways, so how are they different?
  • What are the consequences of being different for same outcome?
  • Well, may be an interview question as well. 😃

I believe, we need to know a bit more than just the ways of achieving it. It is important to know the stories behind the approaches to appreciate possibles outcomes and abuses. Keep reading!

Approach 1: Setting the length property of an array to the value 0(zero).

The simplistic way of doing it is like:

const arr = [ 1, 2, 3, 4, 5 ];
arr.length = 0;

Consequences

This way doesn't mutate the original array reference. It means, if you assign one array reference to other with assignment operator(=), applying this approach on one array will clean the other one too.

Remember, Arrays are non-primitive. If we assign a non-Primitive value to a variable, that variable doesn't actually holds the value, rather holds the reference. Let us understand it better with an example:

const myArray = [ 'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ', 
                  'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                  'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                  'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                  'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                  'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                  'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                  'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                  'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                  'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                  'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                  'blog', 'dot', 'green', 'roots', 'dot', 'info'
                ];

let yourArray = [ 'Some', 'thing' ];

yourArray = myArray;

console.time('Approach 1: .length = 0');
myArray.length = 0;
console.timeEnd('Approach 1: .length = 0');

console.group('Approach 1: Empty array using .length property of the Array')
console.log('myArray =>', myArray);
console.log('yourArray =>', yourArray);
console.groupEnd();

I am doing little more than expected here. I am also calculating the time(in milliseconds) taken to empty the array. Please note, I shall be doing the same for all the approaches so that, we get an idea of the Performance as well.

Coming back to the output:

Approach  1: .length = 0: 0.112ms
Approach  1: Empty array using .length property of the Array
  myArray => []
  yourArray => []

It says,

  • This approach took 0.087ms.
  • As we see, both myArray and yourArray are emptied now.

Learning

In a situation like the one demonstrated above, if you have two references to the same array, and you empty one of the array using arr.length = 0, both references will now point to the same empty array.

Hence the learning is, don’t use this technique if you don’t want other array also to be an empty array in a situation like this!

Approach 2: Assign a reference to a New array

It is as simple as doing:

let arr = [ 1, 2, 3, 4, 5 ];
arr = [];

Consequences

This method mutates the original array reference. It assigns the reference to an empty array to the original variable. Let us understand this by an example:

let hisArray = [ 'Some', 'thing' ];

let herArray = [ 'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ', 
                    'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                    'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                    'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                    'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                    'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                    'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                    'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                    'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                    'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                    'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                    'blog', 'dot', 'green', 'roots', 'dot', 'info'
                ];

herArray = hisArray;

console.time('Approach  2: new assignment');
hisArray = [];
console.timeEnd('Approach  2: new assignment');

console.group('Approach  2: Empty array by assigning a new empty Array []')
console.log('hisArray =>', hisArray);
console.log('herArray =>', herArray);
console.groupEnd();

Output of this would be:

Approach  2: new assignment: 0.005ms
Approach  2: Empty array by assigning a new empty Array []
  hisArray => []
  herArray => [ 'Some', 'thing' ]

As you notice,

  • This approach took lesser time than the previous one, i.e, just 0.005 ms
  • The Original array hisArray is changed however the other value for the array herArray is still unchanged.

Learning

This approach is a suitable only if you don't have other references to the original array. You should be careful enough with this approach because, if you have reference to this array from another variable, the original array will remain unchanged. This might lead to the Memory Leak.

Hence the learning is, use this if you only reference the array by its original variable.

BREAK TIME

matt-hoffman-310320-unsplash.jpg Image Courtesy: unsplash.com

I have used the term reference few times. It is really important to understand the concept of reference and value for Primitive and Non-Primitive types.

In case you need, please have a look into this:

LET'S CONTINUE...

Let us continue discussing the other approaches. How about them?

Approach 3: Use pop() till the end

Another approach could to use the pop() method of Array to remove an element. So what to do when want to remove all the elements? Yes! use pop() in loop:

let someArray = [ 'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ', 
                    'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                    'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                    'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                    'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                    'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                    'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                    'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                    'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                    'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                    'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                    'blog', 'dot', 'green', 'roots', 'dot', 'info'
                ];

console.time('Approach  3: pop()');
while(someArray.length > 0) {
    someArray.pop();
}
console.timeEnd('Approach  3: pop()');

console.group('Approach  3: Use pop until death');
console.log('someArray => ', someArray);
console.groupEnd();

... and the output is:

Approach  3: pop(): 0.012ms
Approach  3: Use pop until death
  someArray => []

Consequences

This approach can get things very slow as the number of elements in array grows. You will find a real performance difference between this approach and Previous approaches with higher number of elements in Array.

Learning

Do not use this approach if you have the way to use previous approaches when dealing with large arrays.

Approach 4: Use splice!

You can use the splice method on array to empty the Array and it is as Convenient as the Approach 1 and 2. But, it comes with a Hidden Cost!

let names = [ 'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ', 
                'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                'blog', 'dot', 'green', 'roots', 'dot', 'info'
            ];

console.time('Approach  4: splice()');
let spliced = names.splice(0, names.length);
console.timeEnd('Approach  4: splice()');

console.group('Approach  4: Use splice!');
console.log('names => ', names);
console.log('spliced => ', spliced )
console.groupEnd();

Give a close look into the output here:

Approach  4: splice(): 0.005ms
Approach  4: Use splice!
  names =>  []
  spliced =>  [ 'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ', 
                'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                'blog', 'dot', 'green', 'roots', 'dot', 'info'
            ]

Consequences

Using .splice() works perfectly and the performance is also good! But since the .splice() function will return an array with all the removed items, it will actually return a copy of the original array.

TADAAAAA! Do you see that in output above?

Learning

Do not use this approach if you do not have to take the overhead of the returned copy of the original array. There may be use-cases where you need it but, I would love to hear about those!

Approach 5: How about Shift()?

Here is our last approach, using shift() method. What does shift() do?

The shift() method removes the first element from an array and returns that removed element.

Have a look into the code below:

let againNames = [ 'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ', 
                    'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                    'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                    'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                    'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                    'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                    'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                    'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                    'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                    'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                    'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
                    'blog', 'dot', 'green', 'roots', 'dot', 'info'
                ];

console.time('Approach  5: shift()');
while (againNames.length > 0) {
    againNames.shift();
}
console.timeEnd('Approach  5: shift()');

console.group('Approach  5: How about Shift()?');
console.log('againNames', againNames);
console.groupEnd();

... and the output:

Approach  5: shift(): 0.027ms
Approach  5: How about Shift()?
  againNames []

Consequences/Learning

It is slower and doesn't make much sense to use it when other better approaches are described above.

Conclusion

In my day to day code reviews, I have seen the usage of Approach # 1 and 2 heavily for Emptying the Array,

  • Usage of .length()
  • Assigning new Array

Please note, the use-case of removing one/few(or specific) elements from an array and Emptying it(Remove All) fully are different. Hence these need to be thought out differently.

Each of these approaches got its own Consequences(Advantages and Disadvantages) and scope/time to use. Another point to note that, Performance could be key too in determining the approach for your implementation.

If you are interested to try out these approaches with different array structures, use this live benchmark site to do it.


There is a popular saying by Francis Bacon,

“Knowledge is power.”

I dare to extend it as,

Sharing is empowering.

Hope you Liked the story. Keep learning and Keep sharing. Cheers 🍻!!!

Tapas Adhikary

I love writing on various topics like JavaScript, Latest ECMAScript, React, Angular, Leadership and Management. I go by sharing what I value as Great Learning. Big Foodie and Voracious Reader.

Write your comment…

Be the first one to comment