What are the spread and rest operators in JavaScript?
Both use ... but do opposite things: spread expands an iterable into individual elements; rest collects multiple elements into an array.
JavaScript
Overview
The three-dot `...` syntax serves two complementary purposes depending on where it appears: **spread** expands an array or object into individual elements (unpacking); **rest** collects remaining elements into a new array or object (packing).
Key Points
- •Spread in a call: `fn(...arr)` passes array elements as arguments.
- •Spread in a literal: `[...arr]` or `{...obj}` creates a shallow copy.
- •Object spread merges objects: `{ ...defaults, ...overrides }` - later keys win.
- •Rest in params: `function fn(a, b, ...rest)` collects extra arguments.
- •Rest in destructuring: `const [first, ...others] = arr` collects remaining.
- •Both only do a **shallow** copy of objects and arrays.
Examples
Spread: copy and merge arrays
javascriptconst a = [1, 2, 3];
const b = [4, 5, 6];
const combined = [...a, ...b]; // [1, 2, 3, 4, 5, 6]
const copy = [...a]; // [1, 2, 3] (shallow copy)
const withItem = [0, ...a, 99]; // [0, 1, 2, 3, 99]Spread: merge objects (last key wins)
javascriptconst defaults = { theme: 'light', lang: 'en', fontSize: 14 };
const userPrefs = { theme: 'dark', fontSize: 18 };
const config = { ...defaults, ...userPrefs };
// { theme: 'dark', lang: 'en', fontSize: 18 }
// userPrefs.theme overrides defaults.themeSpread: pass array as function arguments
javascriptconst numbers = [3, 1, 4, 1, 5, 9];
Math.max(...numbers); // 9 - spread as individual args
Math.max.apply(null, numbers); // old way to do the sameRest: collect extra function arguments
javascriptfunction sum(first, ...rest) {
return rest.reduce((acc, n) => acc + n, first);
}
sum(1, 2, 3, 4); // 10 - first=1, rest=[2,3,4]Rest: destructuring remainder
javascriptconst [head, ...tail] = [1, 2, 3, 4];
console.log(head); // 1
console.log(tail); // [2, 3, 4]
const { id, ...rest } = { id: 1, name: 'Alice', role: 'admin' };
console.log(id); // 1
console.log(rest); // { name: 'Alice', role: 'admin' }Pro Tip
Object spread `{ ...obj }` is the cleanest way to immutably update an object: `const updated = { ...user, name: "Bob" }`. This is the pattern used in React state updates and Redux reducers to avoid mutating the original.