Destructuring in JavaScript
Destructuring lets you unpack values from arrays or properties from objects into distinct variables using a syntax that mirrors the structure you are extracting from. It arrived in ES6 and quickly became one of the most-used features in modern JavaScript.
Object Destructuring
The most common form works with objects. You wrap the target variables in curly braces and JavaScript matches them by property name:
const user = {
name: "Alice",
email: "alice@example.com",
location: "London"
};
// Extract name and email into their own variables
const { name, email } = user;
console.log(name); // "Alice"
console.log(email); // "alice@example.com"
The variable names must match the object keys. If you need different names, rename them:
const { name: userName, email: userEmail } = user;
console.log(userName); // "Alice"
console.log(userEmail); // "alice@example.com"
Array Destructuring
Arrays are destructured by position rather than keys. The order matters:
const rgb = [255, 128, 64];
const [red, green, blue] = rgb;
console.log(red); // 255
console.log(green); // 128
console.log(blue); // 64
Skip elements by leaving gaps:
const [first, , third] = [1, 2, 3];
console.log(first); // 1
console.log(third); // 3
Default Values
When a property might be undefined, provide a fallback:
const person = { name: "Bob" };
// Without defaults — role becomes undefined
const { name, role } = person;
console.log(role); // undefined
// With defaults — role gets a default
const { name: n, role = "guest" } = person;
console.log(role); // "guest"
This works for arrays too:
const [x = 0, y = 0, z = 0] = [1, 2];
console.log(z); // 0 (default used)
Rest Pattern
Collect remaining properties or elements into a new variable using three dots:
const user = {
id: 1,
username: "alice",
email: "alice@example.com",
verified: true
};
// Extract id and username, collect the rest
const { id, username, ...details } = user;
console.log(id); // 1
console.log(username); // "alice"
console.log(details); // { email: "alice@example.com", verified: true }
With arrays:
const [first, second, ...rest] = [1, 2, 3, 4, 5];
console.log(first); // 1
console.log(second); // 2
console.log(rest); // [3, 4, 5]
Nested Destructuring
Pull values from deeply nested structures:
const config = {
server: {
host: "localhost",
port: 3000
},
database: {
name: "app_db",
pool: 10
}
};
// Extract deeply nested values
const { server: { host, port }, database: { name } } = config;
console.log(host); // "localhost"
console.log(port); // 3000
console.log(name); // "app_db"
Destructuring Function Parameters
Clean up function signatures by destructuring arguments directly:
function greet({ name, greeting = "Hello" }) {
return `${greeting}, ${name}!`;
}
const message = greet({ name: "Alice", greeting: "Hi" });
console.log(message); // "Hi, Alice!"
// Works with missing properties too
const fallback = greet({ name: "Bob" });
console.log(fallback); // "Hello, Bob!"
This pattern eliminates the need for options.greeting || "Hello" inside the function body.
Common use case: destructuring the event object in React or DOM handlers:
function handleClick({ target, currentTarget }) {
console.log(`Clicked element: ${target.tagName}`);
console.log(`Handler attached to: ${currentTarget.tagName}`);
}
Swapping Variables
Array destructuring makes swapping two values trivial:
let a = 1;
let b = 2;
[a, b] = [b, a];
console.log(a); // 2
console.log(b); // 1
No temporary variable needed.
Common Mistakes
Referencing a non-existent property without a default
const { missing } = {}; // No error, but missing is undefined
This is fine unless you destructure later and expect a value.
Forgetting that object destructuring uses keys, not position
const { a, b } = { a: 1, b: 2 }; // Works
const { a, b } = [1, 2]; // Works, but extracts from indices
The second line works because arrays have numeric keys, but it is confusing. Do not do it.
Mutating the original object
Destructuring creates new variables. It does not modify the source:
const original = { count: 0 };
const { count } = original;
count = 5; // TypeError: Assignment to constant variable
// Use let if you need to reassign
Practical Example
Extracting API response data:
// Typical API response
const response = {
status: 200,
data: {
users: [
{ id: 1, name: "Alice", email: "alice@example.com" },
{ id: 2, name: "Bob", email: "bob@example.com" }
],
pagination: { page: 1, total: 2 }
},
timestamp: "2026-03-11T12:00:00Z"
};
// Pull out what you need
const {
status,
data: {
users,
pagination: { page, total }
}
} = response;
console.log(`Page ${page} of ${total}, got ${users.length} users`);
Without destructuring, you would write response.data.pagination.page multiple times. With destructuring, you extract once and use page directly.
See Also
- JavaScript Closures Explained — Understand scope and how destructuring interacts with closures
- Array.prototype.map() — Often paired with destructuring for transforming extracted data
- Array.prototype.filter() — Use with destructuring to extract and filter in one step