Destructuring
Destructuring
Destructuring is a convenient way to extract values from arrays or properties from objects into distinct variables. It makes your code cleaner and more readable.
Array Destructuring
Basic syntax:
const numbers = [1, 2, 3];
// Old way
const first = numbers[0];
const second = numbers[1];
// Destructuring
const [first, second, third] = numbers;
console.log(first); // 1
console.log(second); // 2
console.log(third); // 3
Skipping elements:
const colors = ["red", "green", "blue", "yellow"];
const [primary, , tertiary] = colors; // Skip green
console.log(primary); // "red"
console.log(tertiary); // "blue"
Default values:
const [a, b, c, d = "default"] = [1, 2, 3];
console.log(a); // 1
console.log(d); // "default" (not in array)
Rest pattern:
const [first, ...rest] = [1, 2, 3, 4, 5];
console.log(first); // 1
console.log(rest); // [2, 3, 4, 5]
Swapping variables:
let x = 1;
let y = 2;
[x, y] = [y, x]; // Swap!
console.log(x); // 2
console.log(y); // 1
Object Destructuring
Basic syntax:
const person = {
name: "Alice",
age: 25,
city: "NYC"
};
// Old way
const name = person.name;
const age = person.age;
// Destructuring
const { name, age, city } = person;
console.log(name); // "Alice"
console.log(age); // 25
console.log(city); // "NYC"
Renaming variables:
const person = { name: "Alice", age: 25 };
// Rename 'name' to 'userName'
const { name: userName, age: userAge } = person;
console.log(userName); // "Alice"
console.log(userAge); // 25
console.log(name); // ReferenceError - 'name' doesn't exist
Default values:
const person = { name: "Alice" };
const { name, age = 18, country = "USA" } = person;
console.log(name); // "Alice"
console.log(age); // 18 (default)
console.log(country); // "USA" (default)
Rest pattern:
const person = {
name: "Alice",
age: 25,
city: "NYC",
country: "USA"
};
const { name, ...address } = person;
console.log(name); // "Alice"
console.log(address); // { age: 25, city: "NYC", country: "USA" }
Nested Destructuring
Nested objects:
const user = {
id: 1,
name: "Alice",
address: {
city: "NYC",
country: "USA"
}
};
const {
name,
address: { city, country }
} = user;
console.log(name); // "Alice"
console.log(city); // "NYC"
console.log(country); // "USA"
console.log(address); // ReferenceError - we didn't assign 'address'
Nested arrays:
const data = ["Alice", 25, ["NYC", "USA"]];
const [name, age, [city, country]] = data;
console.log(name); // "Alice"
console.log(age); // 25
console.log(city); // "NYC"
console.log(country); // "USA"
Function Parameters
Destructuring in function parameters:
// Instead of this:
function displayUser(user) {
console.log(user.name);
console.log(user.age);
console.log(user.city);
}
// Do this:
function displayUser({ name, age, city }) {
console.log(name);
console.log(age);
console.log(city);
}
displayUser({ name: "Alice", age: 25, city: "NYC" });
With default values:
function createUser({ name, age = 18, role = "user" }) {
return { name, age, role };
}
console.log(createUser({ name: "Alice" }));
// { name: "Alice", age: 18, role: "user" }
console.log(createUser({ name: "Bob", role: "admin" }));
// { name: "Bob", age: 18, role: "admin" }
Default parameter object:
function configure({ theme = "light", lang = "en" } = {}) {
console.log(theme, lang);
}
configure({ theme: "dark" }); // "dark" "en"
configure({}); // "light" "en"
configure(); // "light" "en" - {} is default
Array parameters:
function plotPoint([x, y]) {
console.log(`Point at (${x}, ${y})`);
}
plotPoint([10, 20]); // "Point at (10, 20)"
Practical Examples
Example 1: API Response Handling
// Typical API response
const response = {
data: {
user: {
id: 1,
name: "Alice",
email: "alice@example.com"
},
posts: [/* ... */]
},
status: 200,
message: "Success"
};
// Extract what you need
const {
data: { user: { name, email }, posts },
status
} = response;
console.log(name); // "Alice"
console.log(email); // "alice@example.com"
console.log(status); // 200
Example 2: React Props
// Common React pattern
function UserCard({ name, age, avatar, isOnline = false }) {
return (
<div className="user-card">
<img src={avatar} alt={name} />
<h3>{name}</h3>
<p>Age: {age}</p>
{isOnline && <span className="online-badge">Online</span>}
</div>
);
}
// Usage
<UserCard
name="Alice"
age={25}
avatar="/alice.jpg"
isOnline={true}
/>
Example 3: Multiple Return Values
function getCoordinates() {
return [40.7128, -74.0060]; // NYC coordinates
}
const [latitude, longitude] = getCoordinates();
console.log(`Lat: ${latitude}, Long: ${longitude}`);
Example 4: Config Objects
function connectDatabase({
host = "localhost",
port = 5432,
database,
username,
password,
ssl = false,
...options
}) {
console.log(`Connecting to ${host}:${port}/${database}`);
console.log(`SSL: ${ssl}`);
console.log("Additional options:", options);
}
connectDatabase({
database: "myapp",
username: "admin",
password: "secret",
timeout: 5000,
retries: 3
});
Example 5: Loop Destructuring
const users = [
{ id: 1, name: "Alice", age: 25 },
{ id: 2, name: "Bob", age: 30 },
{ id: 3, name: "Charlie", age: 35 }
];
// Destructure in loop
for (const { name, age } of users) {
console.log(`${name} is ${age} years old`);
}
// Or with map
const names = users.map(({ name }) => name);
console.log(names); // ["Alice", "Bob", "Charlie"]
Example 6: State Updates (React)
const [user, setUser] = useState({
name: "Alice",
preferences: { theme: "dark", language: "en" }
});
// Update nested property
setUser(prev => ({
...prev,
preferences: {
...prev.preferences,
theme: "light"
}
}));
// Destructure to read
const { name, preferences: { theme } } = user;
Common Patterns
1. Extracting from arrays returned by functions:
const match = /(\d+)-(\d+)-(\d+)/.exec("2024-01-15");
const [, year, month, day] = match; // Skip first element
console.log(year, month, day); // "2024" "01" "15"
2. Excluding properties:
const user = {
id: 1,
name: "Alice",
password: "secret123",
email: "alice@example.com"
};
// Remove password from object
const { password, ...safeUser } = user;
console.log(safeUser); // { id: 1, name: "Alice", email: "..." }
3. Renaming and defaults together:
const config = { apiUrl: "https://api.example.com" };
const {
apiUrl: baseUrl,
timeout: maxTimeout = 5000,
retries: maxRetries = 3
} = config;
console.log(baseUrl); // "https://api.example.com"
console.log(maxTimeout); // 5000
console.log(maxRetries); // 3
Gotchas and Tips
1. Can’t destructure null or undefined:
const { name } = null; // TypeError!
// Use default empty object
const { name } = someValue || {}; // Safe
// Or optional chaining with default
const { name } = someValue ?? {};
2. Computed property names:
const key = "username";
const { [key]: value } = { username: "alice123" };
console.log(value); // "alice123"
3. Mixed patterns:
const data = {
id: 1,
items: [10, 20, 30]
};
const {
id,
items: [first, ...restItems]
} = data;
console.log(id); // 1
console.log(first); // 10
console.log(restItems); // [20, 30]
When to Use Destructuring
✅ Good use cases:
- Extracting data from API responses
- Function parameters with multiple options
- React component props
- Working with arrays/objects in loops
- Renaming variables for clarity
❌ When to avoid:
- Simple single-property access:
obj.nameis clearer thanconst { name } = obj - Deeply nested structures that make code hard to read
- When you need the whole object anyway
Next Article: The ’this’ Keyword