stackademic

The leading education platform for anyone with an interest in software development.

Spread & 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 undefined in 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