Spread Operator
Spread (...) unpacks a collection into its individual items. It is the everyday tool for copying and combining data without changing the original — the foundation of React state updates.
On this page · 5 min · Intermediate
On this page
- Learning objectives
- Explanation
- Syntax
- Code example
- Step by step
- Real-world use
- Common mistakes
- Best practices
- Remember this
- Practice exercise
- Mini quiz
- Related topics
- My notes
- Reading time
- 5 min
- Difficulty
- Intermediate
- Updated
- Oct 28, 2026
Related tutorials
Learning objectives#
- Spread arrays, strings and Sets
- Copy and merge objects with overrides
- Update items immutably
- Explain why spread is shallow and when to use structuredClone
Explanation#
Anything iterable can be spread into an array: [...array], [...'text'], [...new Set(list)], [...map.entries()].
Objects can be spread into objects: { ...defaults, ...userSettings }. Later properties override earlier ones.
Immutable update: create a new array/object with the change instead of editing the original — items.map(t => t.id === id ? { ...t, done: true } : t).
Spread is shallow: it copies only the top level. Nested objects are shared between the copy and the original. Use structuredClone(obj) for a deep copy.
Syntax#
const all = [...a, ...b];
const settings = { ...defaults, theme: 'dark' };
Code example: Spread recipes#
console.log([...'hello']);
console.log([...new Set([1, 2, 2, 3, 3])]);
const user = { name: 'Asha', address: { city: 'Pune' } };
const copy = { ...user, name: 'Ravi' };
copy.address.city = 'Delhi'; // nested object is shared!
console.log(user.name, user.address.city);
const deep = structuredClone(user);
deep.address.city = 'Goa';
console.log(user.address.city);
const todos = [{ id: 1, done: false }, { id: 2, done: false }];
const updated = todos.map(t => (t.id === 2 ? { ...t, done: true } : t));
console.log(updated[1], todos[1]);
[ 'h', 'e', 'l', 'l', 'o' ]
[ 1, 2, 3 ]
Asha Delhi
Delhi
{ id: 2, done: true } { id: 2, done: false }Step-by-step explanation#
- A string is iterable, so spreading gives its characters.
- A Set removes duplicates; spreading turns it back into an array.
- copy got its own name, but address still points to the same object, so changing the city changed user too.
- structuredClone makes a full deep copy, so the original stays Delhi.
- map + spread builds a new todo for id 2 and leaves the original array untouched.
Real-world use case#
React: setUser({ ...user, name }) and setTodos(todos.map(…)). Redux reducers and Angular signals use the same immutable-update pattern.
Common mistakes#
Nested objects and arrays are shared. Spread each level you change, or use structuredClone.
{ theme: 'dark', ...settings } — settings.theme wins because it comes later. Put overrides after the spread.
Math.max(...bigArray) with hundreds of thousands of items can exceed the argument limit. Use reduce for very large arrays.
Best practices#
- Copy before changing shared data
- Put overrides after the spread
- Spread every nested level you modify
- Use [...new Set(arr)] to remove duplicates
Remember this#
Spread = open the box and pour the items out.
Last one wins: { ...a, x: 1 } sets x to 1.
Spread is one level deep — nested objects are shared.
Practice exercise#
Your task: Given const state = { user: { name: "Asha", city: "Pune" }, theme: "light" }, create a new state with city "Mumbai" without changing the original.
Need a hint?
Show solution
const state = { user: { name: 'Asha', city: 'Pune' }, theme: 'light' };
const next = { ...state, user: { ...state.user, city: 'Mumbai' } };
console.log(next.user.city, state.user.city); // Mumbai Pune
Mini quiz#
What is printed?
const a = { x: 1, y: 2 };
const b = { ...a, y: 9 };
console.log(b);
Want more? Practise all ES6+ MCQs · ES6+ interview questions
My notes#
Saved in this browser.