Destructuring and the Spread Operator
Unpacking arrays and objects into variables, and spreading them into new ones.
2 min read
Destructuring and spread are two sides of the same idea — pulling values apart and putting them back together — and together they replace a lot of manual indexing and looping in everyday JavaScript.
Array destructuring
const coordinates = [10, 20, 30];
const [x, y, z] = coordinates;
console.log(x, y, z); // 10 20 30Positions map directly to variable names, and you can skip entries with a blank:
const [first, , third] = coordinates;
console.log(first, third); // 10 30Object destructuring
const user = { name: "Ada", age: 36, email: "ada@example.com" };
const { name, age } = user;
console.log(name, age); // Ada 36Unlike arrays, object destructuring matches by key name, not position. You can rename while destructuring, and provide a default for a missing key:
const { name: userName, country = "unknown" } = user;
console.log(userName, country); // Ada unknownThis is especially common for function parameters, where it avoids options.foo, options.bar repeated throughout the function body:
function createUser({ name, age = 18 }) {
return `${name} (${age})`;
}
createUser({ name: "Grace" }); // "Grace (18)"The spread operator
... expands an array or object into its individual elements — the reverse of destructuring's "pull apart," it's "spread out."
const nums = [1, 2, 3];
const moreNums = [...nums, 4, 5];
console.log(moreNums); // [1, 2, 3, 4, 5]
const original = { name: "Ada", age: 36 };
const updated = { ...original, age: 37 };
console.log(updated); // { name: "Ada", age: 37 }Spreading into a new object or array creates a shallow copy rather than mutating the original — updated is a distinct object from original. This pattern ({ ...original, key: newValue }) is the standard way to update state immutably, which matters a lot in frameworks like React that rely on detecting when an object reference has actually changed.
Rest: the same syntax, gathering instead of spreading
... also appears on the receiving end of a destructure, where it collects the remaining items instead of expanding them:
const [head, ...tail] = [1, 2, 3, 4];
console.log(head, tail); // 1 [2, 3, 4]
const { name, ...rest } = user;
console.log(name, rest); // Ada { age: 36, email: "ada@example.com" }Whether ... spreads or gathers depends entirely on where it appears — inside a literal being built (spread) versus inside a pattern being destructured (rest).
Next up: template literals, a string syntax that makes building strings out of variables — something you'll do constantly once working with destructured data — much cleaner.