DEV Community

Cover image for You Deleted the Array Element. Except You Didn't.
Byte Corner
Byte Corner

Posted on Originally published at bytecorner.dev

You Deleted the Array Element. Except You Didn't.

The Array Still Has Three Elements

In Javascript, delete looks like a natural way to remove something from an array.

You have an element at index 1. You delete it. Surely the array becomes shorter.

Not quite.

delete removes the property at that index. The array itself stays the same length, leaving a hole behind.

🔴 The Problem

Consider this:

const users = ["Alice", "Bob", "Charlie"];

delete users[1];

console.log(users);
console.log(users.length);
Enter fullscreen mode Exit fullscreen mode

You might expect:

["Alice", "Charlie"]
2
Enter fullscreen mode Exit fullscreen mode

Instead, the array still has a length of 3:

["Alice", empty, "Charlie"]
3
Enter fullscreen mode Exit fullscreen mode

The important part is that index 1 is now missing.

You can prove it:

console.log(1 in users); // false
console.log(users.length); // 3
Enter fullscreen mode Exit fullscreen mode

The array did not shift "Charlie" from index 2 to index 1.

You removed the property at index 1 and left a hole where it used to be.

🟢 The Solution

If you mean "remove this element and shift everything after it," use splice():

const users = ["Alice", "Bob", "Charlie"];

users.splice(1, 1);

console.log(users);
console.log(users.length);
Enter fullscreen mode Exit fullscreen mode

Now the result is what you probably expected:

["Alice", "Charlie"]
2
Enter fullscreen mode Exit fullscreen mode

splice() actually changes the array by removing the element and moving the later elements down.

If you do not want to mutate the original array, modern JavaScript also gives you toSpliced():

const users = ["Alice", "Bob", "Charlie"];

const remaining = users.toSpliced(1, 1);
Enter fullscreen mode Exit fullscreen mode

Now users stays unchanged, while remaining contains the shorter array.

⚡ The Part That Bites

The really interesting part is that a hole is not the same as undefined.

Compare these:

const a = ["Alice", undefined, "Charlie"];

const b = ["Alice", "Bob", "Charlie"];
delete b[1];
Enter fullscreen mode Exit fullscreen mode

Reading index 1 gives undefined in both cases:

console.log(a[1]); // undefined
console.log(b[1]); // undefined
Enter fullscreen mode Exit fullscreen mode

But the index exists in a and does not exist in b:

console.log(1 in a); // true
console.log(1 in b); // false
Enter fullscreen mode Exit fullscreen mode

You can see the same difference with Object.keys():

console.log(Object.keys(a)); // ["0", "1", "2"]
console.log(Object.keys(b)); // ["0", "2"]
Enter fullscreen mode Exit fullscreen mode

That difference can also show up when you iterate.

For example, forEach() skips the hole entirely:

b.forEach((value) => {
  console.log(value);
});
Enter fullscreen mode Exit fullscreen mode

This prints only:

Alice
Charlie
Enter fullscreen mode Exit fullscreen mode

There is no callback for the missing index.

That is where a seemingly harmless delete can become a debugging headache. The array can still have the same length, but code iterating over it may no longer see every index you think is there.

🧠 The Takeaway

Arrays are objects with numeric properties and a length property.

So when you write:

delete users[1];
Enter fullscreen mode Exit fullscreen mode

you are deleting a property. You are not asking JavaScript to remove an element and close the gap.

Think of it like this:

delete      -> remove the property at that index
splice      -> remove the element and shift the array
Enter fullscreen mode Exit fullscreen mode

And if you need an immutable version:

toSpliced   -> create a new array without the element
Enter fullscreen mode Exit fullscreen mode

The dangerous part is not that delete fails.

It does exactly what JavaScript asked it to do.

The problem is that what JavaScript means by "delete this array element" is probably not what you meant.

Top comments (1)

Collapse
 
jonrandy profile image
Jon Randy 🎖️ •

The properties are actually still strings, just like other objects. When you access them with a number, type coercion occurs.