Destructuring & Spread — Pulling Data Apart
BeginnerDestructuring extracts values from objects and arrays into variables; spread and rest do the reverse. Together they remove most of the boilerplate around passing data around.
Overview
These two features do more to make modern JavaScript readable than anything else in the 2015 release. Destructuring in a function signature documents what the function needs. Rest parameters collect the remainder. Spread copies and merges. In React you will see all three in almost every component, and the patterns are worth being fluent in rather than looking up.
Object and Array Destructuring
Objects destructure by name, arrays by position. Both support defaults and renaming.
// Objects — by name
const { name, role = 'student' } = user
const { name: userName } = user // rename
const { address: { city } } = user // nested
// Arrays — by position
const [first, second] = items
const [, , third] = items // skip with commas
const [head, ...tail] = items // rest
// Swapping without a temp variable
let a = 1, b = 2
;[a, b] = [b, a]
// In a for-of over entries
for (const [key, value] of Object.entries(obj)) { ... }In Function Signatures
This is where destructuring earns its place: the signature becomes documentation.
// Without — the caller has to remember argument order
function createUser(name, email, role, active) { ... }
createUser('Asha', 'a@b.com', undefined, true) // what is undefined?
// With — named, defaulted, order-free
function createUser({ name, email, role = 'student', active = true }) { ... }
createUser({ name: 'Asha', email: 'a@b.com', active: true })
// The = {} makes the whole argument optional
function paginate({ page = 1, size = 20 } = {}) { ... }
paginate() // works
// React props, the same pattern
function Badge({ label, tone = 'neutral', children }) { ... }Spread vs Rest
Same three dots, opposite jobs, told apart by position: rest on the left of an assignment collects, spread on the right expands.
// REST — collects (left side / parameter list)
const [first, ...others] = [1, 2, 3] // others = [2, 3]
const { id, ...fields } = record
function log(level, ...messages) { ... }
// SPREAD — expands (right side / call site / literal)
const combined = [...listA, ...listB]
const merged = { ...defaults, ...overrides }
Math.max(...numbers)
const copy = [...original]
// Common React shape — pass everything through except what you consumed
function Input({ label, ...inputProps }) {
return <><span>{label}</span><input {...inputProps} /></>
}Key Points to Remember
- 1Objects destructure by name and arrays by position; both support defaults and renaming
- 2A destructured parameter object turns positional arguments into named ones the caller cannot mis-order
- 3Adding `= {}` to a destructured parameter lets the caller omit the argument entirely
- 4Rest collects on the left of an assignment; spread expands on the right — same syntax, opposite direction
- 5The { consumed, ...rest } pattern is how React components pass unknown props through to a DOM element
Interview Questions
Sign in to ask AriaWhat is the difference between rest and spread, given they use the same syntax?
How would you swap two variables without a temporary one?
Why is a destructured options object often better than positional parameters?
Ask Aria about Destructuring & Spread — Pulling Data Apart
Your personal AI tutor — ask anything about this concept
Revision Status
Personal Notes
Sign in to save personal notes for this topic.
Discussion
Sign in to join the discussion.