JavaScript Destructuring, Spread, and Rest Operators Explained

Destructuring, spread, and rest all use similar-looking syntax (... and bracket patterns) but do genuinely different things — worth being precise about which is which.

// Destructuring: extract values into named variables
const { name, age = 18 } = { name: 'Alice' }; // age defaults to 18
const [first, second, ...remaining] = [1, 2, 3, 4, 5];

// Spread: expand an iterable into individual elements
const combined = [...[1, 2], ...[3, 4]];       // [1, 2, 3, 4]
const merged = { ...{a: 1}, ...{b: 2} };        // {a: 1, b: 2}
console.log(Math.max(...[3, 1, 4, 1, 5]));      // spread into function arguments

// Rest: collect remaining items into an array/object (opposite of spread)
function sum(...numbers) {                       // rest parameter
    return numbers.reduce((a, b) => a + b, 0);
}
const { id, ...otherProps } = { id: 1, name: 'x', active: true };

The way to tell spread and rest apart despite identical ... syntax: spread expands a collection (used where a value is expected), rest collects values (used in a destructuring pattern or function parameters) — context determines which one you’re looking at.