Spread and rest use the same ... syntax but solve opposite problems. Spread expands arrays/objects into individual values, while rest collects multiple values into one array. Interview-ready understanding includes function arguments, object/array usage, shallow-copy caveats, and when each improves clarity.
Spread operator vs rest parameters in JavaScript
The Core Idea
Spread and rest share the same syntax (...) but do opposite jobs:
- Spread breaks one value into many.
- Rest collects many values into one.
If you remember direction, you almost never confuse them:
spread = expand, rest = gather.
Feature | Where used | Behavior | Example |
|---|---|---|---|
Spread operator | Function calls, array literals, object literals | Expands iterable/object into individual entries. |
|
Rest parameters | Function parameter list, destructuring patterns | Collects remaining values into array/object. |
|
// SPREAD: expand
const nums = [2, 3, 4];
console.log(Math.max(...nums)); // 4
const merged = [1, ...nums, 5];
console.log(merged); // [1, 2, 3, 4, 5]
// REST: gather
function sum(label, ...values) {
const total = values.reduce((acc, n) => acc + n, 0);
return `${label}: ${total}`;
}
console.log(sum('total', 10, 20, 30)); // 'total: 60'
Function Arguments: Most Common Interview Angle
- Use spread when a function expects separate arguments but you have an array.
- Use rest when you want a function that accepts variable argument count cleanly (instead of old
arguments).
Rest parameters are real arrays, so you can directly call map, filter, reduce on them.
function average(...values) {
if (values.length === 0) return 0;
return values.reduce((a, b) => a + b, 0) / values.length;
}
const scores = [80, 90, 100];
console.log(average(...scores)); // 90
Arrays and Objects: Useful Patterns
Spread is heavily used for immutable updates (React/Redux-style state updates). Rest is useful when extracting known fields and keeping the remainder.
// Array copy + append (shallow copy)
const a = [1, 2];
const b = [...a, 3];
// Object copy + override (shallow copy)
const user = { id: 1, name: 'Ada', role: 'viewer' };
const admin = { ...user, role: 'admin' };
// Object rest in destructuring
const { role, ...publicUser } = admin;
console.log(role); // 'admin'
console.log(publicUser); // { id: 1, name: 'Ada' }
Common Pitfalls
- Rest must be last in function parameters and destructuring.
- Spread is shallow for arrays/objects; nested objects are still shared references.
- You can spread iterables into arrays/calls, but plain object spread follows object own-enumerable keys, not iterable protocol.
- Very large spreads in function calls can hurt readability and may hit argument limits in extreme cases.
// Rest must be last (SyntaxError):
// function bad(...rest, x) {}
// Shallow copy caveat
const state = { prefs: { theme: 'light' } };
const clone = { ...state };
clone.prefs.theme = 'dark';
console.log(state.prefs.theme); // 'dark' (same nested object reference)
Need | Use | Why |
|---|---|---|
Pass an array into a multi-arg function | Spread | Converts one container into individual arguments. |
Accept unknown number of arguments | Rest | Collects variable inputs into one array. |
Immutable top-level object/array update | Spread | Creates concise shallow copies with overrides. |
Extract known keys and keep leftovers | Rest in destructuring | Separates explicit fields from remaining data. |
Practical scenario
You are normalizing API payloads in a frontend dashboard. You keep known fields (id, name) and forward unknown metadata for telemetry without mutating source objects.
Common pitfalls
- Assuming spread does deep cloning.
- Using rest with huge parameter lists where structured input object is clearer.
- Forgetting that rest in object destructuring only captures remaining own enumerable properties.
Write tests for nested reference behavior, not just top-level equality, when using spread in reducers or utility helpers.
Imagine unpacking groceries: spread is taking everything out of one bag onto the counter. Rest is putting all leftover items into one bag after keeping what you need first.
- Spread expands. Rest collects.
- Same token (
...), different context and intention. - Prefer them for readable argument handling and immutable state updates.
- Remember shallow-copy behavior when nested objects exist.
Use the relevant interview-question hub first, then move into a concrete study plan before targeted company sets.