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 passwordCommon 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.