jsguides

Array.prototype.fill()

fill(value[, start[, end]])

The fill() method changes all elements in an array to a static value from a start index (inclusive) to an end index (exclusive). It mutates the original array and returns a reference to the same array. The value argument can be any type: number, string, object, or undefined.

A common trap: if you fill with an object, every slot gets a reference to the same object, not independent copies. Mutating one slot mutates all of them. For independent objects, use Array.from with a mapping function instead.

Syntax

fill(value)
fill(value, start)
fill(value, start, end)

Parameters

ParameterTypeDefaultDescription
valueany-The value to fill the array with
startnumber0Start index (inclusive). Negative values count from the end.
endnumberarray.lengthEnd index (exclusive). Negative values count from the end.

Return value

The modified array. Because fill() mutates in place and returns the same array reference, chaining off the return value works but can be confusing.

Examples

Basic usage

const arr = [1, 2, 3, 4, 5];
arr.fill(0);
console.log(arr);
// [0, 0, 0, 0, 0]

// Fill a specific range
const nums = [1, 2, 3, 4, 5];
nums.fill(9, 1, 3);
console.log(nums);
// [1, 9, 9, 4, 5]

When filling only part of an array, the start and end arguments let you target a specific slice. These values can also be negative, counting from the end of the array instead of the beginning. This is especially handy when you don’t know the array length ahead of time.

Using negative indices

const arr = [1, 2, 3, 4, 5];
// Start at second-to-last, fill to end
arr.fill(0, -2);
console.log(arr);
// [1, 2, 3, 0, 0]

// Fill middle portion
arr.fill('x', 1, -1);
console.log(arr);
// [1, 'x', 'x', 'x', 0]

Negative indices are resolved as length + index, so -1 refers to the last element, -2 to the second-to-last, and so on. This convention makes end-relative fills readable without computing absolute positions. Pass negative values for both start and end to carve out a range measured from the tail.

Creating initialized arrays

// Create an array of zeros
const zeros = new Array(5).fill(0);
console.log(zeros);
// [0, 0, 0, 0, 0]

// Create a 2D matrix with independent rows
const matrix = Array(3).fill(null).map(() => Array(3).fill(0));
console.log(matrix);
// [[0, 0, 0], [0, 0, 0], [0, 0, 0]]

The fill(null).map(() => Array(3).fill(0)) pattern is the correct way to create a 2D array with independent rows. Using .fill([]) would give all rows the same array reference.

Common patterns

Beyond basic array filling, fill() handles several recurring tasks worth keeping in your toolbox:

Initializing a buffer:

const buffer = new ArrayBuffer(16);
const bytes = new Uint8Array(buffer).fill(0xFF);

When you reuse an array across multiple rounds—for example, a scoreboard that resets between games—fill(0) clears the values without allocating a new array. This avoids triggering garbage collection for the old array and keeps memory churn low.

Resetting an array in place:

let scores = [10, 20, 30, 40, 50];
scores.fill(0);
console.log(scores);
// [0, 0, 0, 0, 0]

Pair fill() with map() to generate computed sequences. By filling a sparse array with a dummy value first, you ensure map() visits every slot—sparse arrays skip empty indices. This technique works because new Array(5) creates an array with no actual slots, and fill(null) makes every position dense before mapping.

Generating a sequence placeholder before mapping:

const indices = Array(5).fill(null).map((_, i) => i * 10);
console.log(indices);
// [0, 10, 20, 30, 40]

fill() is often used just to make the array dense so map() visits every index, since sparse arrays skip empty slots.

Object reference trap

When you fill an array with an object, every element points to the same object in memory - not independent copies. This catches many developers off guard:

const bad = new Array(3).fill({ count: 0 });
bad[0].count = 5;
console.log(bad);
// [{ count: 5 }, { count: 5 }, { count: 5 }] - all mutated!

// Correct approach: use Array.from to create independent objects
const good = Array.from({ length: 3 }, () => ({ count: 0 }));
good[0].count = 5;
console.log(good);
// [{ count: 5 }, { count: 0 }, { count: 0 }] - only [0] changed

The same trap applies to arrays: new Array(3).fill([]) gives three references to the same array. Always use Array.from with a factory function when you need distinct objects at each index.

When fill() is the better option

fill() is the right tool when you want to initialize or reset a block of array slots to the same value. That makes it handy for placeholders, buffers, counters, and quick setup code where the actual data will arrive later. Because it mutates in place, it is especially useful when you already have an array and simply want to overwrite its current contents.

The main thing to watch is whether the value is primitive or a reference. Primitive values are copied as expected, but objects and arrays are shared by reference, which can create surprising coupling between slots. When you need distinct items, use a factory function instead of fill() alone.

TypedArray support

fill() is also available on typed arrays (Uint8Array, Float32Array, etc.) with the same signature. This is the standard way to zero-out or initialize a typed buffer:

const buffer = new Float32Array(8);
buffer.fill(0);   // all zeros
buffer.fill(1.0, 4);  // first 4 stay 0, last 4 become 1.0

See Also