Difficulty: Intermediate
Destructuring is a concise syntax introduced in ES6 that lets you unpack values from arrays or properties from objects into distinct variables. Instead of accessing each value with bracket or dot notation across multiple lines, destructuring lets you extract exactly what you need in a single declaration. It dramatically improves readability, reduces boilerplate, and is used everywhere in modern JavaScript and React codebases.
Array destructuring uses square bracket syntax on the left side of an assignment. The variables are matched by position - the first variable gets the first element, the second gets the second, and so on. You can skip elements by leaving gaps with commas, provide default values that kick in when the extracted value is undefined, and use the rest syntax (...) to capture all remaining elements into a new array. A particularly elegant use case is swapping two variables without a temporary variable: [a, b] = [b, a].
Object destructuring uses curly brace syntax and matches by property name rather than position. This means the order of variables does not matter - what matters is that the variable names match the property keys. You can rename variables using the colon syntax ({ name: fullName }), provide defaults for missing properties, and destructure nested objects by mirroring the nesting structure on the left side. The rest syntax works here too, collecting all remaining properties into a new object.
Function parameter destructuring is where this feature truly shines. Instead of receiving an options object and accessing its properties inside the function body, you can destructure the parameter right in the function signature. This makes the function's expected inputs immediately visible and lets you provide sensible defaults at the definition site. React component props are universally destructured this way, and it is considered idiomatic in modern JavaScript.
Combining destructuring with other features like computed property names, template literals, and array methods creates a powerful and expressive vocabulary for data manipulation. Once you internalize destructuring, you will find yourself using it reflexively - it becomes the natural way to work with structured data in JavaScript.
const rgb = [255, 128, 0];
// Basic
const [red, green, blue] = rgb;
console.log(red, green, blue);
// Skip elements
const [, , justBlue] = rgb;
console.log(justBlue);
// Default values
const [a, b, c, d = 255] = rgb;
console.log(d);
// Swap variables
let x = 'hello';
let y = 'world';
[x, y] = [y, x];
console.log(x, y);
Destructuring assigns array elements by position. The comma gaps skip elements. Default values are used when the position is undefined (d defaults to 255 since rgb has no fourth element). The swap trick works because the right side creates a temporary array [y, x] before the left side destructures it.
const response = {
status: 200,
data: {
user: { name: 'Alice', email: 'alice@dev.io' },
token: 'abc123'
},
headers: { 'content-type': 'application/json' }
};
// Rename with colon syntax
const { status: httpStatus } = response;
console.log(httpStatus);
// Nested destructuring
const { data: { user: { name, email }, token } } = response;
console.log(name, email, token);
// Rest: collect remaining properties
const { status, ...rest } = response;
console.log(Object.keys(rest));
The colon renames status to httpStatus. Nested destructuring mirrors the object structure to reach deeply nested values in one statement. The rest operator (...rest) collects everything except status into a new object containing data and headers.
// Without destructuring - hard to read
function createUser(options) {
const name = options.name;
const role = options.role || 'viewer';
const active = options.active !== undefined ? options.active : true;
return { name, role, active };
}
// With destructuring - clean and declarative
function createUserV2({ name, role = 'viewer', active = true }) {
return { name, role, active };
}
console.log(createUserV2({ name: 'Bob' }));
console.log(createUserV2({ name: 'Carol', role: 'admin', active: false }));
Parameter destructuring with defaults makes the function signature self-documenting. You can see exactly what properties are expected and what their default values are. The V2 version is functionally equivalent to the verbose V1 but far more readable.
// Array rest
const [first, second, ...remaining] = [10, 20, 30, 40, 50];
console.log(first);
console.log(remaining);
// Object rest - useful for separating known from unknown props
const props = { id: 1, className: 'card', onClick: '...', 'data-testid': 'card-1' };
const { id, className, ...htmlProps } = props;
console.log(id, className);
console.log(htmlProps);
The rest element must always be last. In the array case, it collects the remaining elements into a new array. In the object case, it collects the remaining properties into a new object - this pattern is very common in React for forwarding unknown props to underlying HTML elements.
array destructuring, object destructuring, default values, renaming, nested destructuring, function parameter destructuring, variable swapping, rest in destructuring