Object Destructuring
Destructuring is a compact syntax for pulling values out of an object into named variables. It reads like reverse object literal syntax: instead of building an object from variables, you break an object back into variables. Once you internalise it, you will see it almost everywhere modern code passes data around.
The basic form
const user = { name: "Ada", age: 36, email: "ada@example.com" };
const { name, age } = user;
console.log(name); // Ada
console.log(age); // 36The pattern on the left mirrors the shape of the object on the right. Keys that are not mentioned are simply skipped.
Renaming on the way out
When the property name does not match the variable name you want, use key: newName. Read it as "take key and call it newName".
const apiResponse = { user_id: 42, full_name: "Ada Lovelace" };
const { user_id: id, full_name: name } = apiResponse;
console.log(id, name); // 42 'Ada Lovelace'Default values
Add = value after a name to provide a fallback. The default only kicks in when the property is undefined — not for null, 0 or "".
const { theme = "light", fontSize = 14 } = { fontSize: 18 };
console.log(theme, fontSize); // light 18
const { value = "fallback" } = { value: null };
console.log(value); // null — null is NOT undefinedRenaming plus default
const { theme: appTheme = "light" } = {};
console.log(appTheme); // 'light'Read as: "take theme (default 'light'), and call it appTheme".
Nested destructuring
The pattern can match nested shapes. Each level reuses the same syntax.
const response = {
status: 200,
data: {
user: { id: 42, name: "Ada" },
pagination: { page: 1, perPage: 20 },
},
};
const {
data: {
user: { id, name },
pagination: { page },
},
} = response;
console.log(id, name, page); // 42 'Ada' 1Destructuring function parameters
Destructuring shines in function signatures. Replace a generic options argument with a precise list of fields, and pair it with defaults to get optional named parameters.
function createUser({ name, age = 18, isAdmin = false } = {}) {
return { name, age, isAdmin };
}
console.log(createUser({ name: "Ada", age: 36 }));
// { name: 'Ada', age: 36, isAdmin: false }
console.log(createUser());
// { name: undefined, age: 18, isAdmin: false }The = {} after the pattern is what lets you call createUser() with no argument. Without it, destructuring undefined throws.
Rest in destructuring
Use ...rest at the end of a destructuring pattern to collect the leftover properties into a new object.
const user = { id: 42, name: "Ada", age: 36, email: "ada@example.com" };
const { id, ...publicFields } = user;
console.log(publicFields); // { name: 'Ada', age: 36, email: 'ada@example.com' }This is a clean way to omit a property when forwarding data — far better than delete, because it leaves the original untouched.
Destructuring an already-declared variable
Without const/let, the parser thinks the curly brace starts a block. Wrap the assignment in parentheses to disambiguate.
let a, b;
({ a, b } = { a: 1, b: 2 });
console.log(a, b); // 1 2Common idioms in real code
React props:
function Button({ label, onClick, disabled = false }).Express handlers:
app.get("/u/:id", (req, res) => { const { id } = req.params; ... }).Module imports — destructuring of a namespace:
const { readFile } = require("fs/promises").Swapping/extracting from results:
const { data, error } = await load().