Destructuring and Spread/Rest
Destructuring and Spread/Rest in JavaScript
Pattern matching, unpacking, property renaming, and immutable array/object updates.
The Unpacking Suitcase and the Lego Bucket
Destructuring extracts properties from objects and arrays into distinct variables. The spread syntax unpacks collections, while the rest parameter collects multiple elements into an array.
Array Destructuring (Ordered)
Extracts values based on index position: `const [first, , third] = items;`. Allows easy variable swapping: `[a, b] = [b, a]`.
Object Destructuring (Keyed)
Extracts values by property key: `const { name, age = 18 } = user;`. Supports renaming: `const { name: fullName } = user;`.
Rest Pattern (...)
Must be the last element in a destructuring pattern. Captures all remaining properties or arguments into a new array or object.
Spread Syntax (...)
Expands an iterable into individual elements. Commonly used for shallow cloning (`{ ...obj }`, `[...arr]`) and merging.
Nested destructuring, variable swapping, and immutable updates with spread:
// 1. Variable swap without temp variable
let x = 1, y = 2;
[x, y] = [y, x];
console.log("Swapped:", { x, y });
// 2. Nested object destructuring with defaults and renaming
const config = {
server: { host: "127.0.0.1", port: 8080 },
version: "v2.4"
};
const {
server: { host, port: serverPort },
timeout = 5000 // Default value
} = config;
console.log(`Connecting to ${host}:${serverPort} (timeout: ${timeout}ms)`);
// 3. Immutable update with Spread & Rest
const originalUser = { id: 101, role: "admin", status: "offline" };
const updatedUser = { ...originalUser, status: "online", lastLogin: Date.now() };
const { id, ...publicProfile } = updatedUser;
console.log("Public profile without ID:", publicProfile);
Swapped: { x: 2, y: 1 }
Connecting to 127.0.0.1:8080 (timeout: 5000ms)
Public profile without ID: { role: 'admin', status: 'online', lastLogin: 1789290000000 }
Destructuring null or undefined
The Risk: `const { name } = null` or `const [a] = undefined` throws `TypeError: Cannot destructure property of null/undefined`.
The Fix: Provide fallback defaults when destructuring function arguments: `function showUser({ name } = {}) { ... }`.
Spread Performs Only Shallow Copies
The Risk: Modifying nested objects in `{ ...original }` also mutates `original` because nested object references are copied directly.
The Fix: Use `structuredClone()` or spread nested levels individually.
- ✓ Array destructuring is positional; Object destructuring matches property keys.
- ✓ Renaming syntax: `{ originalKey: newVariableName }`.
- ✓ Default values: `{ key = defaultValue }`.
- ✓ Rest (`...`) collects remaining items; must always be at the end.
- ✓ Spread (`...`) unpacks items; only clones shallowly.