Spread & Rest

Three dots (...) that expand or collect values.

Spread: Arrays

Expand an array into individual elements.

const nums = [1, 2, 3];

// Spread into a new array:
const copy = [...nums];        // [1, 2, 3]

// Combine arrays:
const a = [1, 2];
const b = [3, 4];
const merged = [...a, ...b];   // [1, 2, 3, 4]

// Add elements:
const withExtra = [0, ...nums, 4]; // [0, 1, 2, 3, 4]

// Spread into function arguments:
Math.max(...nums);             // 3
console.log(...nums);          // 1 2 3

const merged = [...a, ...b]

[1, 2]
→ spread →
1234
[1,2,3,4]

Spread: Objects

Copy and merge object properties.

const defaults = { theme: "light", lang: "en", fontSize: 14 };
const userPrefs = { theme: "dark", fontSize: 16 };

// Merge (later values win):
const config = { ...defaults, ...userPrefs };
// { theme: "dark", lang: "en", fontSize: 16 }

// Clone an object:
const clone = { ...original };

// Add/override properties:
const updated = { ...user, lastLogin: new Date() };

⚠️ Object spread creates a shallow copy. Nested objects are still shared references. Use structuredClone() for deep copies.

Rest Parameters

Collect remaining arguments into an array.

// Collect all arguments:
function sum(...numbers) {
  return numbers.reduce((total, n) => total + n, 0);
}
sum(1, 2, 3);     // 6
sum(1, 2, 3, 4, 5); // 15

// Mix named + rest:
function log(level, ...messages) {
  console.log(`[${level}]`, ...messages);
}
log("ERROR", "Failed to", "connect");
// [ERROR] Failed to connect

// Rest must be last:
function bad(a, ...rest, b) {} // ✗ SyntaxError!

...spread (expand)

[...arr] or fn(...arr)

Unpacks into individual values

...rest (collect)

fn(...args) or {...rest}

Packs individual values into one

Rest in Destructuring

Collect remaining properties/elements.

// Object rest:
const { id, ...rest } = { id: 1, name: "Alice", age: 28 };
// id = 1
// rest = { name: "Alice", age: 28 }

// Array rest:
const [first, ...others] = [10, 20, 30, 40];
// first = 10
// others = [20, 30, 40]

// Useful for removing properties:
const { password, ...safeUser } = userWithPassword;
// safeUser has everything except password

Common Patterns

Real-world spread/rest usage.

Immutable array operations

const arr = [1, 2, 3];

// Add to end (instead of push):
const added = [...arr, 4];

// Remove by index:
const removed = [...arr.slice(0, 1), ...arr.slice(2)];

// Replace at index:
const replaced = [...arr.slice(0, 1), 99, ...arr.slice(2)];

React state patterns

// Update object state:
setUser({ ...user, name: "New Name" });

// Add to array state:
setItems([...items, newItem]);

// Remove from array state:
setItems(items.filter(i => i.id !== targetId));

Function composition

// Forward all arguments:
function wrapper(...args) {
  console.log("Calling with:", args);
  return originalFn(...args);
}

FAQ

Common questions about spread and rest.