Suggest an editImprove this articleRefine the answer for “Destructuring assignment in JavaScript”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**Destructuring assignment** is a JavaScript (ES6) syntax that extracts values from arrays or properties from objects into separate variables in one step. ```javascript const [a, b] = [1, 2]; const { name } = { name: 'Alice' }; console.log(a, name); // 1 'Alice' ``` **Key:** defaults apply only when the value is `undefined`, not `null` or `0`.Shown above the full answer for quick recall.Answer (EN)Image**Destructuring assignment** is a JavaScript syntax that pulls values from arrays or properties from objects into individual variables, in one step instead of multiple manual assignments. ## Theory ### TL;DR - Think of it like unpacking a labeled box: you name each slot and pull only what you need - Arrays match by **position**; objects match by **key name** - Defaults apply only when the value is `undefined`, not when it is `null` or `0` - Rest (`...`) collects remaining items and must always come last - Use it when extracting 2+ values; for a single value, dot notation is cleaner ### Quick example ```javascript // Array: position-based const [first, second] = [10, 20, 30]; console.log(first); // 10 console.log(second); // 20 // Object: key-based const user = { name: 'Alice', age: 25 }; const { name, age } = user; console.log(name); // 'Alice' console.log(age); // 25 ``` The engine reads left-to-right: for arrays it uses indices, for objects it looks up the property name. The compiled output is equivalent to manual assignment, so there is no performance difference. ### When to use - **API responses** with multiple fields: `const { data, error } = await fetchUser(id)` - **Function parameters** from an object: `function greet({ name, role = 'user' }) {}` - **Variable swapping**: `[a, b] = [b, a]` without a temp variable - **React hooks**: `const [count, setCount] = useState(0)` - **Named imports**: `import { useState, useEffect } from 'react'` Skip it for a single value. `user.name` is more readable than `const { name } = user` when that is all you need. ### Array patterns **Skipping elements** uses an empty slot: ```javascript const [first, , third] = [1, 2, 3]; console.log(third); // 3 ``` **Rest** gathers the remaining items: ```javascript const [head, ...tail] = [1, 2, 3, 4]; console.log(tail); // [2, 3, 4] ``` **Defaults** fill in only when the value is `undefined`: ```javascript const [x = 5] = [0]; console.log(x); // 0 (not 5, because 0 is not undefined) ``` ### Object patterns **Rename** a property with a colon after the key: ```javascript const { name: userName } = { name: 'Alice' }; console.log(userName); // 'Alice' ``` **Nested** patterns require nested syntax: ```javascript const { address: { city } } = { address: { city: 'Kyiv' } }; console.log(city); // 'Kyiv' ``` If `address` is `undefined`, this throws a TypeError. Add a default or use optional chaining before destructuring. **Rest** on objects collects all remaining keys: ```javascript const { id, ...rest } = { id: 1, name: 'Alice', age: 25 }; console.log(rest); // { name: 'Alice', age: 25 } ``` ### Common mistakes **Nested destructuring throws on undefined.** ```javascript const data = {}; const { user: { name } } = data; // TypeError: Cannot read properties of undefined ``` Fix: `const { user: { name } = {} } = data` or use `data.user?.name`. **Rest cannot come before the last position.** ```javascript const [...rest, last] = [1, 2, 3]; // SyntaxError ``` Rest must be the final element. `[first, ...rest]` works. `[...rest, last]` does not compile. **Wrong key name when renaming.** ```javascript const { userName } = { name: 'Alice' }; console.log(userName); // undefined ``` `userName` looks for a key literally called `userName`. Use `{ name: userName }` to rename it. **Defaults do not replace `null`.** ```javascript const [x = 5] = [null]; console.log(x); // null (defaults only apply for undefined) ``` ### Real-world usage - **React**: `const [value, setValue] = useState('')`, component props `function Button({ onClick, label })` - **Express/Node.js**: `const { id } = req.params`, `const { page = 1 } = req.query` - **Redux Toolkit**: `const { type, payload: { id } } = action` - **SWR/React Query**: `const { data, error } = useSWR('/api/user')` ### Follow-up questions **Q:** What does `const [x = 1] = [0]` output? **A:** `0`. The default only applies when the value is `undefined`. Zero is a valid defined value. **Q:** What happens when you destructure a key that does not exist on the object? **A:** You get `undefined`. No error is thrown unless you then try to destructure a property of that `undefined` value. **Q:** How do `null` and `undefined` behave differently with defaults? **A:** Only `undefined` triggers the default. `null` passes through as-is. This catches many people off guard during interviews. **Q:** Can you destructure a function return value inline? **A:** Yes. `const [success, data] = await fetchData()` works whenever the function returns an array. **Q:** (Senior) How does V8 compile `const { x } = obj`? **A:** It emits a `GetOwnProperty` check for key `x` on `obj`, then assigns the result to a new binding. Array patterns compile to indexed accesses like `arr[0]`. Rest uses property enumeration or `slice`. The bytecode is equivalent to manual assignment, so there is no runtime overhead. ## Examples ### Basic: arrays and objects ```javascript const coords = [10, 20, 30]; const [x, y] = coords; console.log(x, y); // 10 20 const product = { title: 'Keyboard', price: 99, stock: 5 }; const { title, price } = product; console.log(title, price); // 'Keyboard' 99 ``` Array destructuring picks by index, object destructuring picks by key. A missing key gives `undefined`, not an error. ### Real-world: function params with defaults ```javascript // The expected shape of input is visible right at the signature function handleRequest({ params: { id }, query: { role = 'viewer', page = 1 } }) { console.log(id, role, page); } handleRequest({ params: { id: '42' }, query: { role: 'admin' } }); // '42', 'admin', 1 ``` This pattern appears in React components, Express handlers, and Redux reducers. I find it most useful here: you see what the function expects without reading the body. That alone cuts the time spent understanding unfamiliar code.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.