JavaScript Spread and Rest
Expand iterables with spread and collect remaining values with rest
Overview
The ... operator has two roles: spread expands arrays or objects into individual elements; rest collects remaining items into a new array or object. Same syntax, different positions.
Syntax / Usage
// Spread — arrays
const a = [1, 2]
const b = [...a, 3, 4] // [1, 2, 3, 4]
// Spread — objects (shallow)
const base = { a: 1, b: 2 }
const extended = { ...base, b: 99, c: 3 }
// Rest — function parameters
function sum(first, ...numbers) {
return numbers.reduce((t, n) => t + n, first)
}
// Rest — destructuring
const [head, ...tail] = [1, 2, 3, 4]
const { id, ...fields } = { id: 1, name: 'Ada', role: 'dev' }
Examples
Clone and update state immutably:
setUser((prev) => ({ ...prev, name: 'New Name' }))
setItems((prev) => [...prev, newItem])
Merge configuration objects:
const defaults = { retries: 3, timeout: 5000 }
const userOpts = { timeout: 10000 }
const config = { ...defaults, ...userOpts }
Common Mistakes
- Expecting deep clone from spread—it is shallow only one level
- Spreading
undefinedin object literals is a no-op; spreading undefined in arrays throws - Overusing spread on large arrays where performance matters
- Using rest without it being the final element in destructuring
See Also
destructuring arrays objects array-methods