What is a sparse array — and why map won't fill Array(3)

You want a grid of three zeros. You write new Array(3).map(() => 0). You log it — and get [ <3 empty items> ]. Not a single zero. No error. map just… did nothing.
Here's the tricky part. An array with room for three is not three empty values. It's three holes. And map skips holes. An array like that is called sparse — and it breaks more code than you'd think.
What a sparse array is
A sparse array is an array where some indexes have no element at all. Not undefined, not null — literally nothing.
A regular array is a row of boxes with something in each one. A sparse one is a row where some boxes are missing. But the numbers on the shelf are still there.
Holes show up in three ways:
new Array(3) // [ <3 empty items> ] — three slots, zero elements
const a = []; a[100] = 1 // length 101, one element
delete list[1] // deleted — and left a hole behind
There's a fourth one, by typo: two commas in a row. [1, , 3] is an array with a hole in the middle.
And two sneaky ones. arr.length = 10 stretches a short array — the new slots become holes. And arr[arr.length + 1] = x instead of arr.push(x) is an off-by-one that leaves a hole right before the new element. Adding to the end? Use push — it never makes holes.
How holes behave — the part to remember
Different commands see a hole differently. That's why the bugs feel so mysterious:
const c = [1, , 3]
c.length // 3 — length counts the hole
c.forEach(x => ...) // runs 2 times, skips the hole
c.map(x => x * 2) // [2, <1 empty item>, 6] — hole stays
c.filter(() => true) // [1, 3] — hole dropped
[...c] // [1, undefined, 3] — hole became undefined
JSON.stringify(c) // "[1,null,3]" — and now it's null
Here's the surprise. c.includes(undefined) says true. c.indexOf(undefined) says -1. Same question — "is there an undefined here?" — two different answers.
One more: a plain for (let i = 0; i < c.length; i++) loop does not skip the hole. It honestly hands you undefined. So forEach and for over the same array can count different things. More on loops in loop or map.
Why it matters to you
In practice, holes bite in three places.
Length lies. You put an item into cart[100] because the product id is 100. Now cart.length is 101. The screen says "101 items in cart". There's one. When your keys are ids rather than positions, you want an object, not an array.
An empty grid won't fill. That same Array(3).map(...). People build game boards, calendars, tables this way — and get nothing.
JSON changes the meaning. Save an array with a hole to the server, get null back. And null is not a hole, it's a value. Code that checked "is there an element" suddenly sees that there is. How null differs from "nothing" is in what is null.
There's a hidden cost too. The V8 engine (Chrome, Node.js) stores arrays with holes in a slower mode. And such an array never goes back to the fast mode, even if you fill the holes later. On small arrays you won't notice. On a million elements, you will.
How to make an array without holes
Instead of new Array(n), use Array.from:
Array.from({ length: 3 }, () => 0) // [0, 0, 0]
Array.from({ length: 5 }, (_, i) => i) // [0, 1, 2, 3, 4]
The short version is new Array(3).fill(0). fill fills the holes, and map works after that. But fill has its own trap: put [] or {} in there and every slot gets the same object. For grids of arrays, Array.from with a function is safer.
Removing an element? Not delete — use splice or filter:
list.splice(1, 1) // cut it out, indexes shift
list = list.filter(x => x !== item) // new array without it
And if an AI assistant wrote new Array(n).map(...) for you, that's almost certainly a bug. Ask it to rewrite with Array.from.
How do I spot a hole in the console?
Chrome prints empty × 3, Node.js prints <3 empty items>. To check a specific index, use 1 in arr. A hole gives false; a real undefined gives true.
Isn't a hole the same as undefined?
No. [undefined] is an array with one element whose value is undefined. [ , ] is an array with no elements at all. forEach runs once over the first and zero times over the second.
Are there sparse arrays in Python?
No. You can't "stretch" a Python list by assigning: lst[100] = 1 on a short list fails with IndexError. Holes are a JavaScript thing.
Short story-lessons, an agent simulator and daily practice — in our mobile app. Free.





