Javascript – Undefined array values vs Undefined array indices

Javascript arrays, like any non-primitive, are technically considered objects. This means various object methods and operators are available to them, but internally they’re a different beast. And this can cause unexpected results when treating them like an object.

This is a simple test you can run in your developer console for your browser.

a = [1, 2, 3]
delete a[2]

If javascript arrays act in a similar fashion to a javascript object, you would expect the array to have shrunk by one element.

It doesn’t.

a.length
-> 3

Well, this is strange, and it gets stranger when you print out the array:

a
-> [1, 2, undefined x 1]

Undefined x 1… What does that mean? Every time you delete an array element, it creates an undefined index.

Now, the mystery thickens when you try and play with undefined values.

a.push(undefined)
-> [1, 2, undefined x 1, undefined]

Wait! Why is there undefined x 1, and a separate, different undefined? How are they different? According to the javascript type system, they are the same:

typeof a[2]
-> "undefined"
typeof a[3]
-> "undefined"
typeof a[2] === typeof a[3]
-> true
a[2] === a[3]
-> true
a[2] == a[3]
-> true

A cursory look suggests they’re entirely equivalent, just represented differently. Unfortunately not.

for (property in a) {
    console.log(property + ' ' + a);
}
-> 0 1
-> 1 2
-> 3 undefined

The index itself can be undefined, or the value can be undefined. In our example, a[2] is an undefined index. The index does not exist. Whereas a[3], the index exists, but its value is undefined. This is made apparent when we enumerated over the indices of our array. Ironically, both of them contribute to the overall length of the array, but only one of them holds a value.

If you’re still having trouble conceptualizing this, think of it as such:

a
-> 0 = 1
-> 1 = 2
-> 2 = ???
-> 3 = undefined

a[2] just doesn’t exist. a[3] does, and it is undefined. Careful, the type of a[2] and a[3] are both undefined, which makes some strange literal sort of sense. Now, I could lecture on the importance of understanding the javascript type system until you, my faithful pupils, flee from my blog. But instead, I’ll leave you with this, the simply way of deleting array elements:

a.length = 2
a
-> [1, 2]