The spread syntax ... expands an array into its separate items. It is used inside array literals and function calls.
Copying an array
const original = [1, 2, 3];
const copy = [...original];
copy.push(4);
console.log(original); // → [1, 2, 3]
console.log(copy); // → [1, 2, 3, 4]
The copy is a shallow copy: nested objects are still shared. See Copying Objects.
Merging arrays
const a = [1, 2];
const b = [3, 4];
console.log([...a, ...b]); // → [1, 2, 3, 4]
console.log([0, ...a, 99, ...b]); // → [0, 1, 2, 99, 3, 4]
You can add items between and around the spread parts, which makes it more flexible than concat().
Adding and removing without mutating
This is the pattern that front-end frameworks rely on: build a new array instead of changing the old one.
const todos = ["wash", "study"];
const added = [...todos, "cook"]; // add at the end
const addedFirst = ["wake up", ...todos]; // add at the start
const removed = todos.filter(t => t !== "wash"); // remove
const replaced = todos.map(t => (t === "study" ? "revise" : t)); // replace
console.log(added); // → ["wash", "study", "cook"]
console.log(addedFirst); // → ["wake up", "wash", "study"]
console.log(removed); // → ["study"]
console.log(replaced); // → ["wash", "revise"]
console.log(todos); // → ["wash", "study"]
Spreading into function calls
const scores = [88, 95, 72];
console.log(Math.max(...scores)); // → 95
function add(a, b, c) { return a + b + c; }
console.log(add(...[1, 2, 3])); // → 6
Spreading other iterables
console.log([..."hey"]); // → ["h", "e", "y"]
console.log([...new Set([1, 1, 2])]); // → [1, 2]
Spread vs rest
The same ... has two jobs, depending on where it appears:
- Spread expands a list:
[...a, ...b],fn(...args). - Rest collects the leftovers:
function f(...args),const [first, ...others] = list.
Objects have spread too
{ ...user } copies an object’s properties. See Object Spread and Object.assign.