ylazarenka

Holey JavaScript

Holey JavaScript logo

V8 makes a distinction between two types of arrays: PACKED and HOLEY

// HOLEY — array with holes
const arr = [];
arr[1] = 1; // [ <1 empty item>, 1 ]
// PACKED — array without holes
const arr = [1, 2, 3];

Operations on PACKED arrays are better optimized (“more aggressively”)

Once you create a hole in a packed array, it degrades to HOLEY. HOLEYarrays can't be upgraded back to PACKED arrays — with only one exception, which will be mentioned later. The only way is downward.

Problem

const arr = new Array(150).fill(0);

This one-liner is a clean and simple way to initialize int array with known size. Seems like an idiomatic solution, right?

No

First, new Array(150) creates empty array (array with holes), and only afterwards it's filled with zeros.

As of February 28, 2025, V8 has updated fill() method—it is now the only way to upgrade an array from HOLEY toPACKED. However, this change hasn't been adopted (at least not by nodejs).

You can test it yourself:

# node v23.11.0
node — allow-natives-syntax
Welcome to Node.js v23.11.0.
Type “.help” for more information.
> const arr = new Array(150).fill(0)
undefined
> %DebugPrint(arr)
DebugPrint: 0x1b11c09d0001: [JSArray]
 — map: 0x0eeca718a379 <Map[32](HOLEY_SMI_ELEMENTS)> [FastProperties]
 — prototype: 0x0eeca7182c79 <JSArray[0]>
 — elements: 0x1b11c09d0021 <FixedArray[150]> [HOLEY_SMI_ELEMENTS]
 — length: 150
 — properties: 0x04e0f9cc0d09 <FixedArray[0]>

This is the line we are interested in: elements: 0x1b11c09d0021 <FixedArray[150]> [HOLEY_SMI_ELEMENTS]

It's Good That V8 Fixed this

It would be good if JavaScipt had a truly idiomatic way to initialize array with known size. Here's Go example

arr := make([]int, 150)

That's it — an idiomatic way to initialize array. You don't need to think twice if this the best way. It is. I appreciate that Golang doesn't give me the anxiety that JavaScript does.

The safest way (for now)

const arr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];

Not the cleanest if your array is large, but at least it guarantees a PACKED array. And I wonder if trasnpilers could fix this.

It is what it is

Source: https://v8.dev/blog/elements-kinds