I had a really interesting bug recently that, at first glance, completely stumped me.
I saw I had an array that was empty. But the length was 31.

Wait, what?

## What are dense arrays?

Dense arrays are the most well known type of `Array`. They are the "normal" arrays most are familiar with.

A dense array is an array where the elements are all sequential starting at index 0.

In this instance, the length property of an array accurately specifies the number of elements in the array.

``````let array = [1, 2, 3, 4, 5]
array.length // Returns 5
``````

## What are sparse arrays?

A sparse array is one in which the elements are not sequential, and they don't always start at 0.

They are essentially `Array`s with "holes", or gaps in the sequence of their indices.

So an example would be:

``````let array = [];
array = "Holes now exist";
array.length // 101, but only 1 element``````

Normally, the length property of an `Array` accurately returns the number of elements in the array, but in sparse arrays they don't. If the array is sparse, the value of the length property is greater than the number of elements.

# Why can `Array`s be sparse?

`Array`s under the hood in JavaScript are `Object`s. Their keys are numbers, and their values are the elements.

``````let array = [];
array = {};
array = {};
array = {};
``````

The `length` property on an `Array` takes the last element's index and adds one. So if you have an array with holes between index 0 through 100, and an element at index 101, the `length` will return 101, as it's the last index + 1.

The above happens regardless of how many elements are in the `Array`.

The spec specifically details this behavior if you want to read more on the ECMAScript spec here.

# How do you get a sparse array?

You have seen some ways already, but there are more:

## Use the `Array` object

``````let array = new Array(10); // array initialized with no elements
array.length // 10
``````

## Insert a key/value at a certain index

``````array = 0; // Assignment adds one element
array.length // But .length returns 1001
``````

## Use the `delete` operator

``````let array = [1, 2, 3, 4, 5]
delete array
array.length // .length returns 5
``````

## Initialize an `Array` with holes

``````[,,,,] // You have created an array with nothing but holes
[1,2,3,4,,5] // Oh no, you mistyped a comma and entered a hole between 4 and 5!
``````

## Browser implementation differences

The browser you are on (as well as the version) represents sparse array's holes differently.

Chrome displays this the best (in my opinion) and shows `empty`.

The newest version of Firefox (80.0.1 at the time of witting) shows it like so:

## Conclusion

The final solution of the bug I introduced at the beginning is to just check that the element isn't falsy before using it.  Something like:

``````let array = [,,,,]
for(let i = 0; i < array.length; i++){
if (array[i]) {
console.log(array[i])
}
}
``````

Because the holes are falsy, it won't do the logic you are trying on any holes you have in the `Array`.

So why did my browser show it as empty?

I was using Safari and it showed nothing for the holes. So I  logged out the `Array`'s length which was 31, and when I logged out the contents it just showed me an empty array! Pretty confusing at first glance.