Array.prototype.fill()

Overwrites a range of an array in place with a single static value and returns that array.

Signature
fill(value)
fill(value, start)
fill(value, start, end)
  • Added in JavaScript ECMAScript 2015

Parameters

ParameterTypeDescription
$valueanyThe value written into every slot in the range. If it is an object, every slot references that same object.
$startoptionalnumber= 0Zero-based index to start filling at. Negative values count back from the end.
$endoptionalnumber= array.lengthZero-based index to stop before. Negative values count back from the end.

Return value

ArrayThe same array, modified in place, with the selected range set to value.

Errors

Throws a TypeError if called on null or undefined, or when a target index cannot be written — for example on a frozen array with a non-empty range, which throws in strict and sloppy mode alike. Sealed arrays are unaffected, because sealing leaves existing elements writable.

fill() writes one value into every index from start up to but not including end. It mutates the receiver and returns it, which is what makes the Array(n).fill(v) idiom work: Array(5) produces five empty slots that most array methods skip, and fill() is one of the few methods that writes into holes, turning the array dense in one step.

When to reach for it

Use it to seed a fixed-size buffer (Array(64).fill(0)), to reset a scratch array between iterations without reallocating, or to blank out a slice of a grid row.

What trips people up

  • Objects are shared, not copied. Array(3).fill([]) gives three references to one array, so pushing into arr[0] changes all three. Use Array.from({ length: 3 }, () => []) when each slot needs its own object.
  • It cannot change the length. Filling an empty array does nothing at all — set length or use the Array(n) constructor first.
  • end is exclusive, and both indices are clamped rather than throwing when out of range.

For a non-mutating single-index change, use with() instead.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Build a zero-initialised counter array with Array(26).fill(0).
  • Reset a reusable scratch buffer between loop iterations without allocating a new array.
  • Blank out a slice of a grid row with fill(null, 2, 5).
  • Turn the empty slots left by Array(n) into a dense array before mapping over it.

Frequently asked questions

How do I create an array of n zeros in JavaScript?

Use Array(n).fill(0) — the constructor makes n empty slots and fill() writes a real value into each one. Array(n) alone leaves holes that map() and forEach() silently skip.

Why does changing one element of a filled array change them all?

Because fill() stores the same reference in every slot when you pass an object or array. Build the values per index with Array.from({length: n}, () => ({})) so each slot gets its own object.

Does fill() modify the original array?

Yes, fill() mutates the array in place and returns that same array, so it throws a TypeError on a frozen array — in strict and sloppy mode alike, because fill() always writes with the throwing form of assignment. A sealed array can still be filled, since sealing keeps existing elements writable. Use with() or toSpliced() when you need a copy instead.

More examples

The shared-object trap

fill() evaluates the object literal once, so all three slots point at it and one write shows up in every element. Array.from() calls the factory per index, so only the first object changes.

Example · javascript
const shared = Array(3).fill({ hits: 0 });
shared[0].hits = 1;
console.log(shared);

const independent = Array.from({ length: 3 }, () => ({ hits: 0 }));
independent[0].hits = 1;
console.log(independent);

fill() cannot grow an array

Filling an empty array is a no-op because there are no indexes in range. Setting length first creates the slots; out-of-range start values simply select an empty range instead of throwing.

Example · javascript
const empty = [];
console.log(empty.fill(1), empty.length);

empty.length = 3;
console.log(empty.fill(1));

// Out-of-range indexes are clamped, not errors
console.log([1, 2, 3].fill(0, 10));

Seeding then mapping

map() over Array(4) returns four holes untouched because the callback never runs on empty slots. Filling first makes the array dense so map() visits every index.

Example · javascript
// map() skips holes, so fill() first
console.log(Array(4).map((_, i) => i));
console.log(Array(4).fill(null).map((_, i) => i * i));

// keys() also works and skips the intermediate fill
console.log([...Array(4).keys()]);

Discussion

  • Be the first to comment on this lesson.