Array Destructuring
Array destructuring extracts values by position. You can skip elements, collect the rest, and swap variables without a temp variable.
const colors = ["red", "green", "blue", "yellow"];
// Basic array destructuring
const [first, second] = colors;
console.log(first); // "red"
console.log(second); // "green"
// Skip elements with commas
const [, , third] = colors;
console.log(third); // "blue"
// Swap variables - no temp variable needed!
let a = 1, b = 2;
[a, b] = [b, a];
console.log(a, b); // 2 1
// From function return values
function getMinMax(arr) {
return [Math.min(...arr), Math.max(...arr)];
}
const [min, max] = getMinMax([3, 1, 4, 1, 5, 9]);
console.log(min, max); // 1 9
// Nested array destructuring
const matrix = [[1, 2], [3, 4]];
const [[a1, b1], [c1, d1]] = matrix;
console.log(a1, b1, c1, d1); // 1 2 3 4
Object Destructuring
Object destructuring extracts properties by name. Order does not matter - only the property name matters.
const user = {
name: "Alice",
age: 28,
email: "alice@example.com",
city: "London"
};
// Basic object destructuring
const { name, age } = user;
console.log(name); // "Alice"
console.log(age); // 28
// Order does not matter (unlike array destructuring)
const { city, name: n2 } = user;
console.log(city); // "London"
// Non-existent properties get undefined
const { phone } = user;
console.log(phone); // undefined
// Destructure from function return
function getUserProfile(id) {
return { name: "Bob", age: 25, role: "admin" };
}
const { name: userName, role } = getUserProfile(42);
console.log(userName, role); // "Bob" "admin"
Default Values
Default values are used when the destructured value is undefined.
They do NOT apply to null or any other falsy value.
// Object destructuring with defaults
const config = { host: "localhost" };
const { host, port = 3000, ssl = false } = config;
console.log(host, port, ssl); // "localhost" 3000 false
// Default only applies for undefined
const { host: h2, port: p2 = 8080 } = { host: "api.example.com", port: null };
console.log(p2); // null (null !== undefined - default does NOT apply!)
// Array destructuring with defaults
const [x = 10, y = 20, z = 30] = [1, 2];
console.log(x, y, z); // 1 2 30 (z uses default)
// Combine rename and default
const { name: displayName = "Anonymous" } = {};
console.log(displayName); // "Anonymous"
Renaming Variables
const user = { name: "Alice", id: 1 };
const post = { name: "Hello World", id: 42 };
// Rename to avoid collision when destructuring two objects
const { name: userName, id: userId } = user;
const { name: postTitle, id: postId } = post;
console.log(userName, userId); // "Alice" 1
console.log(postTitle, postId); // "Hello World" 42
// Rename with default value
const settings = {};
const { theme: appTheme = "light", lang: appLang = "en" } = settings;
console.log(appTheme, appLang); // "light" "en"
// API response often uses snake_case - rename to camelCase
const apiResponse = { user_name: "alice", is_admin: true };
const { user_name: username, is_admin: isAdmin } = apiResponse;
console.log(username, isAdmin); // "alice" true
Nested Destructuring
const user = {
name: "Alice",
address: {
city: "London",
zip: "SW1A 1AA",
country: {
code: "GB",
name: "United Kingdom"
}
},
skills: ["JavaScript", "Python", "Go"]
};
// Nested object destructuring
const {
name,
address: { city, zip },
address: { country: { code } }
} = user;
console.log(name, city, zip, code); // "Alice" "London" "SW1A 1AA" "GB"
// Mixed: array inside object, object inside array
const { skills: [primarySkill, ...otherSkills] } = user;
console.log(primarySkill); // "JavaScript"
console.log(otherSkills); // ["Python", "Go"]
// Nested array with defaults
const data = { coords: [10, 20] };
const { coords: [lat = 0, lng = 0, alt = 0] } = data;
console.log(lat, lng, alt); // 10 20 0
Rest in Destructuring
// Array rest - collects remaining elements
const [head, ...tail] = [1, 2, 3, 4, 5];
console.log(head); // 1
console.log(tail); // [2, 3, 4, 5]
const [first, second, ...rest] = "hello".split("");
console.log(first, second, rest); // "h" "e" ["l","l","o"]
// Object rest - collects remaining properties
const user = { name: "Alice", age: 28, city: "London", role: "admin" };
const { name, age, ...otherProps } = user;
console.log(name, age); // "Alice" 28
console.log(otherProps); // { city: "London", role: "admin" }
// Useful for "omitting" properties (create object without a field)
const { password, ...safeUser } = { name: "Alice", email: "a@b.com", password: "secret" };
console.log(safeUser); // { name: "Alice", email: "a@b.com" } - no password!
Function Parameters
Destructuring in function parameters is one of the most practical uses - it gives functions named parameters with optional defaults.
// Without destructuring - verbose
function createUser1(options) {
const name = options.name;
const email = options.email;
const role = options.role || "user";
// ...
}
// With destructuring - clean and self-documenting
function createUser({ name, email, role = "user", active = true } = {}) {
return { name, email, role, active, createdAt: new Date() };
}
console.log(createUser({ name: "Alice", email: "a@b.com" }));
// { name: "Alice", email: "a@b.com", role: "user", active: true, ... }
// Array parameter destructuring
function swap([a, b]) {
return [b, a];
}
console.log(swap([1, 2])); // [2, 1]
// In forEach with entries
const users = [
{ name: "Alice", role: "admin" },
{ name: "Bob", role: "user" },
];
users.forEach(({ name, role }, index) => {
console.log(`${index}: ${name} (${role})`);
});
// 0: Alice (admin)
// 1: Bob (user)
Common Patterns
// 1. Unpack useState in React (array destructuring)
const [count, setCount] = useState(0);
// 2. Unpack useRouter in Next.js (object destructuring)
const { pathname, query, push } = useRouter();
// 3. Unpack API response
const { data: { users, total }, status } = await fetchUsers();
// 4. for...of with Object.entries
const scores = { Alice: 95, Bob: 87, Carol: 92 };
for (const [name, score] of Object.entries(scores)) {
console.log(`${name}: ${score}`);
}
// 5. Import { } is destructuring-like syntax (but not actual destructuring)
import { useState, useEffect } from "react";
// 6. Default export parameter pattern
function App({ title = "My App", theme = "light" } = {}) {
// ...
}
// 7. Immutable update with rest
const updateUser = (user, updates) => ({ ...user, ...updates });
const alice = { name: "Alice", age: 28, city: "London" };
const updated = updateUser(alice, { age: 29 });
console.log(updated); // { name: "Alice", age: 29, city: "London" }