AiTechWorlds
AiTechWorlds
University learning companion
JavaScript Complete 2026 · Spread & Rest Operators
A feature looks correct on a developer’s large monitor but fails on a slow connection and a small screen. Use this topic to inspect structure, state, loading/error behaviour, accessibility and the user journey—not just the happy path.
Use this course-level map to place “Spread & Rest Operators” in the larger system. It complements—not replaces—a topic-specific worked diagram.
The ... syntax does two opposite things depending on context: spread expands an iterable into individual elements, and rest collects multiple elements into an array. Both are fundamental to modern JavaScript patterns.
// Expand an array into elements
const nums = [1, 2, 3];
console.log(...nums); // 1 2 3 (three separate arguments)
// Copy an array (shallow copy)
const original = [1, 2, 3];
const copy = [...original];
copy.push(4);
console.log(original); // [1, 2, 3] — unmodified
console.log(copy); // [1, 2, 3, 4]
// Combine arrays
const a = [1, 2, 3];
const b = [4, 5, 6];
const combined = [...a, ...b]; // [1, 2, 3, 4, 5, 6]
// Add elements at any position
const withPrefix = [0, ...a]; // [0, 1, 2, 3]
const withSuffix = [...a, 7, 8]; // [1, 2, 3, 7, 8]
const inserted = [...a.slice(0,2), 99, ...a.slice(2)]; // [1, 2, 99, 3]
// Spread in function calls
Math.max(...nums); // 3 — same as Math.max(1, 2, 3)
Math.min(...nums); // 1// Copy an object (shallow)
const user = { name: "Alice", age: 30 };
const copy = { ...user };
// Merge objects
const defaults = { theme: "light", language: "en", fontSize: 16 };
const userPrefs = { theme: "dark", language: "fr" };
const settings = { ...defaults, ...userPrefs };
// { theme: "dark", language: "fr", fontSize: 16 }
// Later properties override earlier ones
// Add/override properties immutably
const updated = { ...user, age: 31, city: "NYC" };
// { name: "Alice", age: 31, city: "NYC" } — user unchanged
// Practical: update one field in an object
function updateUser(user, field, value) {
return { ...user, [field]: value };
}
const newUser = updateUser(user, "name", "Bob");
// { name: "Bob", age: 30 }// Pass all props to a child component
function Button({ children, ...props }) {
return <button {...props}>{children}</button>;
}
// Usage
<Button onClick={handleClick} disabled={isLoading} className="btn-primary">
Submit
</Button>
// State updates (never mutate state directly!)
setUser(prevUser => ({ ...prevUser, name: "Bob" }));
setItems(prev => [...prev, newItem]);Rest collects remaining arguments into an array. It must be the last parameter:
// Collect extra 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 regular and rest parameters
function logger(level, ...messages) {
console.log(`[${level}]`, ...messages);
}
logger("ERROR", "File not found", "path:", "/etc/config");
// [ERROR] File not found path: /etc/config
// Rest in arrow functions
const multiply = (factor, ...nums) => nums.map(n => n * factor);
multiply(3, 1, 2, 3, 4); // [3, 6, 9, 12]// Array rest
const [first, second, ...rest] = [1, 2, 3, 4, 5];
console.log(first); // 1
console.log(second); // 2
console.log(rest); // [3, 4, 5]
// Object rest
const { name, age, ...otherProps } = user;
console.log(name, age); // "Alice", 30
console.log(otherProps); // { city: "NYC", role: "admin" }
// Remove a property immutably
function removeKey(obj, keyToRemove) {
const { [keyToRemove]: _, ...remaining } = obj;
return remaining;
}
const noAge = removeKey(user, "age");
// { name: "Alice", city: "NYC", role: "admin" }Before rest parameters, functions used the arguments object:
// Old way — arguments is array-like, not a real array
function oldSum() {
return Array.from(arguments).reduce((a, b) => a + b, 0);
}
// Modern way — rest gives you a real array immediately
const modernSum = (...nums) => nums.reduce((a, b) => a + b, 0);
// Arrow functions don't have arguments — another reason to use rest// Merge defaults with user options
function createConfig(overrides = {}) {
const defaults = {
timeout: 5000,
retries: 3,
verbose: false,
};
return { ...defaults, ...overrides };
}
createConfig({ timeout: 10000 });
// { timeout: 10000, retries: 3, verbose: false }
// Convert NodeList to array (spread works on iterables)
const divs = [...document.querySelectorAll("div")];
divs.forEach(div => div.classList.add("loaded"));
// Convert string to array of chars
const chars = [..."hello"]; // ["h", "e", "l", "l", "o"]
// Unique values
const unique = [...new Set([1, 2, 2, 3, 3, 3])]; // [1, 2, 3]Next lesson: Template Literals powerful string interpolation and tagged templates.
University learning companion
JavaScript Complete 2026 · Spread & Rest Operators
Complete the steps without looking at the answer first; record evidence rather than only a final result.
These are primary or established learning references for this subject. Check the relevant chapter or specification for the exact topic and version.
Get this course's notes on Telegram!
Free cheat sheets, summaries & practice exercises