Skip to main content

The delete operator on an array

delete arr[0] removes the value at index 0, but it does not shift the remaining elements and does not change length: an empty item (a hole) is left in place of the deleted element. Formally the array does not delete an element, it deletes the property with the key 0, which makes the array structure ragged.

Theory

TL;DR

  • The element at index 0 disappears, but its slot stays empty.
  • length does not change: it was 3, it stays 3.
  • The remaining elements are not shifted to the left.
  • A hole appears in the array, a so called empty slot: 0 in arr returns false.
  • Iteration methods (forEach, map, filter) skip empty slots, while a direct read of arr[0] gives undefined.
  • To really remove an element, with a shift, use splice().

Quick example

javascript
const arr = [10, 20, 30]; delete arr[0]; console.log(arr); // [ <1 empty item>, 20, 30 ] console.log(arr.length); // 3

The value 10 is gone, yet the array still has a length of 3.

What happens under the hood

  • delete is an operator for objects: it removes a property. An array in JavaScript is also an object, just one with numeric keys 0, 1, 2 and a special length property.
  • So delete arr[0] literally means "delete the property named 0".
  • The operator does not shift the other elements: the keys 1 and 2 stay where they are.
  • The operator does not touch length: the length is a separate property and is not recalculated automatically.

The result is a hole in the array, a so called empty slot (a sparse array).

Demonstrating the hole

javascript
const arr = [1, 2, 3]; delete arr[1]; console.log(arr); // [1, <1 empty item>, 3] console.log(arr.length); // 3 console.log(1 in arr); // false, the element really is not there

Note the difference between an empty slot and the value undefined:

javascript
const holes = [1, , 3]; // an empty slot const undef = [1, undefined, 3]; // a real undefined value console.log(1 in holes); // false console.log(1 in undef); // true

Both arrays return undefined at index 1, but only in the second case does the property actually exist.

Empty cells behave oddly and easily break the logic of your code.

  • forEach, map, filter, reduce, some, every and Object.keys skip such positions:

    javascript
    const arr = [1, 2, 3]; delete arr[1]; arr.forEach(el => console.log(el)); // logs only 1 and 3
  • But a direct read (arr[1]) gives you undefined, so a check against undefined cannot tell a hole from a real value.

  • Some of the newer methods do the opposite and treat a slot as undefined: Array.from(arr), the spread [...arr], for...of, join(), includes(). Because of that the same array behaves differently in different parts of the code.

  • JavaScript engines optimise dense arrays; a sparse array can push the internal representation into a slower mode.

The correct way to remove an element

Use splice() when you need to remove an element and shift the rest:

javascript
const arr = [10, 20, 30]; arr.splice(0, 1); console.log(arr); // [20, 30] console.log(arr.length); // 2

If mutating the array is not allowed, build a new copy without the unwanted element:

javascript
const arr = [10, 20, 30]; const withoutFirst = arr.slice(1); // [20, 30] const withoutIndex = arr.filter((_, i) => i !== 0); // [20, 30]

For the first and last element there are shorter options: shift() and pop(), and both update length correctly.

A short comparison

MethodWhat it doesChanges lengthCreates a hole?
delete arr[i]removes a propertyNoYes
arr.splice(i, 1)removes an element and shifts the restYesNo
arr.filter(...)returns a new array without the elementThe new array is shorterNo

Conclusion: avoid delete arr[index] for arrays, because it leaves empty slots and makes the structure ragged. For a safe removal use splice().

Common mistakes

  • Expecting length to shrink. It never does: delete knows nothing about array semantics.
  • Assuming the elements will shift. The indexes of the remaining elements stay the same, so after delete arr[0] the expression arr[1] is still the second element.
  • Confusing an empty slot with undefined. Check for presence with i in arr or Object.hasOwn(arr, i), not with arr[i] === undefined.
  • Expecting every method to behave the same. The older iteration methods skip holes, while spread, for...of and Array.from turn them into undefined.
  • Using delete to clear an array. To empty an array use arr.length = 0 or arr.splice(0).
  • Forgetting that delete returns true almost always. A successful return does not mean the array got shorter.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.