JavaScript destructuring explained with simple examples
Destructuring unpacks objects and arrays into variables in one line. Learn renaming, defaults, nested values, function arguments and the undefined error.

What does const { name, age } = user actually do, and why does it show up in every React component and API example?
Short answer: destructuring unpacks values from an object or an array into separate variables in one line. Curly braces {} pull values out of an object by property name, and square brackets [] pull values out of an array by position.
By the end of this post you will destructure objects and arrays, rename values and give them defaults, reach into nested data, destructure function arguments, and fix the error that trips most people up. If objects and arrays are still new, start with What Is An Object (opens in a new tab) and What Is An Array (opens in a new tab).
Object destructuring: pick values by name
Without destructuring, you read each property one at a time:
const user = { name: "Ana", age: 30, address: { city: "Lisbon" } };
const name = user.name;
const age = user.age;With destructuring, it's one line:
const { name, age } = user;
console.log(name, age); // Ana 30The names inside {} must match property names on the object. Order doesn't matter, and you only take what you need. Asking for a property that isn't there gives undefined, not an error.
Rename and set defaults
Use a colon to store a value under a different name, and = to give it a fallback:
const { name: userName, role = "student" } = user;
console.log(userName); // Ana
console.log(role); // student, because user has no roleRead name: userName as "take name and call it userName". You can combine both: { role: userRole = "student" }.
One detail that surprises people: a default only kicks in when the value is undefined. If the property exists and is null, you get null:
const { theme = "light" } = { theme: null };
console.log(theme); // nullReach into nested objects
Put another pair of braces where the nested object is:
const { address: { city } } = user;
console.log(city); // LisbonThis creates a city variable, but not an address one. Keep nesting shallow, though. Two levels is usually where it stops being easier to read than user.address.city.
Array destructuring: pick values by position
Square brackets unpack an array in order:
const scores = [95, 82, 77];
const [first, second] = scores;
console.log(first, second); // 95 82Skip a position with an empty slot, and give defaults the same way as with objects:
const [winner, , third = "none"] = ["Bo", "Ana"];
console.log(winner, third); // Bo noneIt also gives you a neat way to swap two variables without a temporary one:
let a = 1;
let b = 2;
[a, b] = [b, a];
console.log(a, b); // 2 1You've probably seen array destructuring already in React: const [count, setCount] = useState(0) takes the two values useState returns. Our post on useState vs useReducer uses it throughout.
Collect the rest with ...
... gathers whatever you didn't name:
const { name, ...details } = user;
console.log(details); // { age: 30, address: { city: "Lisbon" } }
const [top, ...others] = [95, 82, 77];
console.log(others); // [82, 77]The rest element has to come last. It's a handy way to remove one property, but note that it's a shallow copy: details.address is still the same object as user.address. Our post on value vs reference explains why that matters.
Destructuring (opens in a new tab) and Spread And Rest (opens in a new tab) practice all of this.
Destructuring function arguments
This is where destructuring earns its keep, and where most people get stuck. Instead of accepting an object and reading properties inside, destructure right in the parameter list:
function greet({ name, greeting = "Hi" }) {
return `${greeting}, ${name}`;
}
greet({ name: "Bo" }); // "Hi, Bo"
greet({ name: "Ana", greeting: "Hey" }); // "Hey, Ana"The function's signature now shows exactly which properties it uses, callers can pass them in any order, and optional ones get defaults. Destructuring In Functions (opens in a new tab) practices this.
There's one catch. Call it with nothing and it throws:
greet();
// TypeError: Cannot destructure property 'name' of 'undefined' as it is undefined.You can't destructure undefined. The fix is a default for the whole parameter, = {}:
function greet({ name, greeting = "Hi" } = {}) {
return `${greeting}, ${name}`;
}
greet(); // "Hi, undefined"Now an empty call destructures an empty object instead of crashing. You'll see the same error when an API response is missing a field you destructure from, so it's worth recognizing.
Destructuring in loops
Destructuring works anywhere you declare variables, including loops:
const prices = { popcorn: 4.5, soda: 2.25 };
for (const [item, price] of Object.entries(prices)) {
console.log(`${item}: ${price}`);
}Object.entries() gives you [key, value] pairs, and the brackets unpack each one. Array methods like map and filter take destructured parameters too: users.map(({ name }) => name).
Common mistakes
- Destructuring
undefinedornull.Cannot destructure property 'x' of 'undefined'means the thing on the right didn't exist. Add a default, like= {}on a parameter, or check before you destructure. - Expecting a default to replace
null. Defaults only apply toundefined. Usevalue ?? fallbackifnullshould also fall back. - Assigning to existing variables without parentheses.
{ total } = order;is a syntax error, because a line starting with{looks like a block. Wrap it:({ total } = order);. - Mixing up braces and brackets.
{}matches by name and works on objects.[]matches by position and works on arrays and other iterables. - Nesting too deeply. If a destructuring line is hard to read, pull out one level at a time.
Quick recap
const { a, b } = objtakes properties by name.const [x, y] = arrtakes items by position.name: newNamerenames, and= valuesets a default forundefined....restcollects everything you didn't name, as a shallow copy.- In function parameters, add
= {}so a call with no arguments doesn't crash.
Frequently asked questions
What is destructuring in JavaScript?
It's syntax for unpacking values from objects or arrays into variables. const { name } = user is the same as const name = user.name, and it scales nicely when you need several values at once.
What's the difference between object and array destructuring?
Object destructuring uses {} and matches values by property name. Array destructuring uses [] and matches values by position.
Why do I get "Cannot destructure property of undefined"?
The value on the right side is undefined, often because a function was called without an argument or an API response is missing a field. Add a default, such as = {} on the parameter, or check the value first.
Can I destructure and rename at the same time?
Yes. const { name: userName } = user reads user.name into a variable called userName.
Practice
Try it in your browser, with nothing to install: Destructuring (opens in a new tab) for the basics, then Destructuring (opens in a new tab), Destructuring In Functions (opens in a new tab) and Spread And Rest (opens in a new tab). For more reps, try the JavaScript Objects and JavaScript Arrays challenges.
Where to go next
Destructuring sits in the modern JavaScript module of Intermediate JavaScript (opens in a new tab), right before the course's watchlist project. It pairs naturally with JavaScript array methods, since you'll often destructure inside map() and filter().








