Spread in JavaScript: unpacking an array or object with three dots

Spread unpacks the contents of an array or object right where it is written. Copying, merging, arguments: its three uses and its one limit.
3 min read
Believemy logo

Three dots before a variable, and its contents pour out right where you wrote them. It is one of the few additions to the language that changed how code gets written day to day, especially in interfaces.


Definition

Spread, written with three dots, expands the contents of an iterable, array or string, or the properties of an object, at the exact spot where it appears. It always reads like an opening: where there was a box, there are now its contents.

JAVASCRIPT
const base = [1, 2];

console.log([0, ...base, 3]);   // [0, 1, 2, 3]
console.log([..."abc"]);        // ["a", "b", "c"]

const defaults = { size: "M", color: "black" };
console.log({ ...defaults, color: "red" });
// { size: "M", color: "red" }

That last line shows the behavior to remember on objects: with an identical key, the last write wins. This ordering is what makes it possible to merge default values with supplied ones.


Three uses that come up every day

UseForm
Copy without touching the originalconst copy = [...list]
Merge two objects{ ...defaults, ...options }
Pass an array as argumentsMath.max(...scores)

The first row matters most. Plenty of methods modify the original array, which breaks everything in an interface where the previous value serves as a point of comparison. Copy first, transform second, has become the default reflex.

JAVASCRIPT
const scores = [12, 18, 9];

// Sort without damaging the original array
const sorted = [...scores].sort((a, b) => a - b);

console.log(sorted); // [9, 12, 18]
console.log(scores); // [12, 18, 9], untouched
Good to know

Spread also removes duplicates in one line, paired with a Set: [...new Set(list)]. The set refuses repeats, and the three dots turn it back into an array.


Its limit: the copy stays shallow

This is the classic trap, and it only shows up on nested data.

JAVASCRIPT
const source = { profile: { city: "Lyon" } };
const copy = { ...source };

copy.profile.city = "Paris";
console.log(source.profile.city); // "Paris": the original changed too

Three dots copy the first level only. The nested object is not duplicated, the same memory address gets copied across, so both variables point at it. For a full copy, use structuredClone(source), available in every recent environment.


Frequently asked questions

Question

How does it differ from rest, written the same way?

By position in the line, and nothing else. The same three dots spread contents when used on the right of an assignment or inside a call, and gather values when they appear in a parameter list or on the left of an assignment. The subject is covered in Rest (...).


Question

Can null or undefined be spread?

Inside an object, yes: { ...null } simply yields an empty object, no error. Inside an array, no: [...null] throws a type error, because emptiness is not iterable. It is a surprising asymmetry, and it explains a few crashes on incomplete data.


Question

Why does it show up everywhere in React?

Because a component's state must never be modified in place: a new object has to be supplied for the display to refresh. Three dots produce that copy in one readable expression. Our React course spends real time on this principle, which explains half the rendering bugs beginners hit.

Related terms

Discover our javaScript glossary

Every word of JavaScript explained simply: keywords, built-in objects, methods, errors and concepts. Clear definitions and examples that actually run, to learn and to troubleshoot.

Share this article

Want to help us? Share this article on your networks or even better: on your site, in an article or in your newsletter.