Spread, Rest & Destructuring
Spread, Rest & Destructuring
ES2015 introduced three powerful syntactic features that make working with arrays and objects much more concise: the spread operator, rest parameters, and destructuring assignment.
Spread Operator (...)
The spread operator expands an iterable (array, string, Set, etc.) into individual elements.
Copying and merging arrays:
const a = [1, 2, 3];
const b = [4, 5, 6];
const merged = [...a, ...b]; // [1, 2, 3, 4, 5, 6]
const copy = [...a]; // shallow copySpreading into function arguments:
Math.max(...[3, 1, 4, 1, 5]); // 5Rest Parameters
Rest collects remaining function arguments into an array. It must be the last parameter.
function sum(first, ...rest) {
return rest.reduce((acc, n) => acc + n, first);
}
sum(1, 2, 3, 4); // 10Do not confuse rest parameters (in function signatures) with the spread operator (in call expressions and literals) — they use the same ... syntax but serve opposite purposes.
Array Destructuring
Destructuring lets you unpack array elements into named variables using positional matching.
const [x, y, z] = [10, 20, 30];
const [head, ...tail] = [1, 2, 3, 4]; // head=1, tail=[2,3,4]
const [a = 0, b = 0] = [5]; // a=5, b=0 (default)You can skip elements with commas: const [,second] = [1, 2, 3];
Object Destructuring
Object destructuring unpacks by property name rather than position.
const { name, age } = { name: "Alice", age: 30, city: "NY" };
// Rename: { name: fullName }
// Default: { score = 0 }Nested destructuring:
const { address: { city } } = { address: { city: "London" } };In function parameters:
function greet({ name, title = "User" }) {
return `Hello, ${title} ${name}!`;
}Spread with Objects
Object spread (ES2018) merges objects and creates shallow copies:
const defaults = { theme: "light", lang: "en" };
const config = { ...defaults, lang: "fr" }; // lang overriddenCode Examples
// Merging arrays
const fruits = ["apple", "banana"];
const veggies = ["carrot", "broccoli"];
const food = [...fruits, "grape", ...veggies];
console.log(food);
// Shallow copy (no mutation of original)
const original = [1, 2, 3];
const copy = [...original];
copy.push(4);
console.log("Original:", original);
console.log("Copy:", copy);
// Spread into Math functions
const numbers = [34, 7, 23, 32, 5, 62];
console.log("Max:", Math.max(...numbers));
console.log("Min:", Math.min(...numbers));Spread expands an array in place. Because the spread creates a new array, pushing to copy does not affect the original.
// Rest collects remaining args into an array
function logAll(label, ...items) {
console.log(label + ":", items);
console.log("Count:", items.length);
}
logAll("Colors", "red", "green", "blue");
logAll("Numbers", 1, 2, 3, 4, 5);
// Combining rest with destructuring
function first3([a, b, c, ...rest]) {
console.log("First:", a, b, c);
console.log("Rest:", rest);
}
first3([10, 20, 30, 40, 50]);Rest parameters gather any number of trailing arguments into a real array. You can combine rest with destructuring for expressive parameter handling.
// Array destructuring with defaults and skipping
const [first, , third = 99] = [10, 20];
console.log(first, third); // 10 99
// Swap variables without temp
let x = 1, y = 2;
[x, y] = [y, x];
console.log("Swapped:", x, y);
// Object destructuring with renaming and defaults
const user = { name: "Bob", role: "admin" };
const { name: userName, role, age = 25 } = user;
console.log(userName, role, age);
// Nested object destructuring
const config = { db: { host: "localhost", port: 5432 } };
const { db: { host, port } } = config;
console.log(`${host}:${port}`);
// Destructuring in function params
function display({ title, year = "unknown" }) {
console.log(`${title} (${year})`);
}
display({ title: "Inception", year: 2010 });
display({ title: "Draft" });Destructuring makes variable extraction terse and readable. Defaults handle missing values gracefully, renaming avoids name collisions, and nested destructuring reaches into deep structures in a single expression.
Quick Quiz
1. What does the rest parameter syntax (...args) do in a function definition?
2. What is printed by: const [a, , b] = [1, 2, 3]; console.log(a, b);
3. Which statement correctly merges two objects, with obj2 properties overriding obj1?
Was this lesson helpful?