Working with arrays and objects means constantly extracting values. Before destructuringWhat is destructuring?A shorthand for pulling specific values out of an object or array into their own variables instead of accessing them one by one. existed, you had to write repetitive lines like const name = user.name; const age = user.age; for every property. Destructuring gives you a concise syntax for this, while the spread operatorWhat is spread operator?The three-dot syntax (...) that expands an array or object into its individual elements, commonly used to copy or merge collections. makes copying and merging effortless. Together they eliminate dozens of lines of boilerplateWhat is boilerplate?Repetitive, standardized code that follows a known pattern and appears in nearly every project - like setting up a server or wiring up database connections. code and are used everywhere in modern JavaScript and React.
Object destructuringWhat is destructuring?A shorthand for pulling specific values out of an object or array into their own variables instead of accessing them one by one.
Instead of accessing properties one by one:
const user = { name: "Alice", age: 25, email: "alice@example.com" };
// Old way - repetitive
const name = user.name;
const age = user.age;
// Destructuring - one line
const { name, age, email } = user;
console.log(name); // "Alice"
console.log(age); // 25
console.log(email); // "alice@example.com"The variable names must match the property names exactly. If you write const { nme } = user, you get undefined because there is no property called nme.
Renaming variables
Sometimes you want a different variable name than the property name:
const { name: userName, age: userAge } = user;
console.log(userName); // "Alice"
console.log(userAge); // 25
// name and age are NOT defined - only userName and userAge existThis is especially useful when destructuring from two objects with overlapping property names, or when a property name conflicts with an existing variable.
Default values
Provide fallbacks for missing properties:
const user = { name: "Alice" };
const { name, age = 18, role = "user" } = user;
console.log(age); // 18 (default - property was missing)
console.log(role); // "user" (default)Defaults only kick in when the value is undefined. If the property exists but is null or 0, the default is not used.
Nested destructuring
Extract values from nested objects:
const user = {
name: "Alice",
address: {
city: "Paris",
country: "France"
}
};
const { name, address: { city, country } } = user;
console.log(city); // "Paris"
console.log(country); // "France"
// note: address itself is NOT defined as a variableconst { data: { users: [{ name, address: { city } }] } } = response. This is fragile and unreadable. If the API response shape changes even slightly, the entire destructuring breaks with a cryptic error like TypeError: Cannot destructure property 'users' of undefined. Keep destructuring to one or two levels deep. For anything deeper, use intermediate variables: const users = response.data.users then destructure from there. Also watch for AI destructuring properties that might not exist, always add defaults for optional nested values or use optional chaining first.Array destructuringWhat is destructuring?A shorthand for pulling specific values out of an object or array into their own variables instead of accessing them one by one.
Extract array elements by position:
const colors = ["red", "green", "blue"];
const [first, second, third] = colors;
console.log(first); // "red"
console.log(second); // "green"
console.log(third); // "blue"| Pattern | Syntax | Result |
|---|---|---|
| Basic | const [a, b] = arr | First two elements |
| Skip items | const [a, , c] = arr | First and third |
| Rest | const [a, ...rest] = arr | First + remaining array |
| Defaults | const [a = 1] = [] | Fallback if missing |
| Swap | [a, b] = [b, a] | Swap two variables |
// Skip elements with commas
const [first, , third] = colors;
// Rest pattern - capture remaining elements
const [head, ...tail] = colors;
console.log(head); // "red"
console.log(tail); // ["green", "blue"]Array destructuring is commonly used with functions that return arrays, like React's useState:
const [count, setCount] = useState(0);
// count = 0, setCount = the setter functionSpread operatorWhat is spread operator?The three-dot syntax (...) that expands an array or object into its individual elements, commonly used to copy or merge collections.
The spread operator (...) expands an iterable into individual elements. It looks identical to the restWhat is rest?An architectural style for web APIs where URLs represent resources (nouns) and HTTP methods (GET, POST, PUT, DELETE) represent actions on those resources. syntax but works in the opposite direction: rest collects, spread expands.
Spreading arrays
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const combined = [...arr1, ...arr2]; // [1, 2, 3, 4, 5, 6]
const copy = [...arr1]; // [1, 2, 3] - shallow copy
const extended = [0, ...arr1, 4]; // [0, 1, 2, 3, 4]Spreading objects
const defaults = { theme: "light", notifications: true };
const userPrefs = { theme: "dark" };
// Merge objects - later properties overwrite earlier ones
const settings = { ...defaults, ...userPrefs };
console.log(settings); // { theme: "dark", notifications: true }structuredClone().RestWhat is rest?An architectural style for web APIs where URLs represent resources (nouns) and HTTP methods (GET, POST, PUT, DELETE) represent actions on those resources. parameters in functions
Rest syntax (also ...) collects remaining arguments into an array:
function sum(...numbers) {
return numbers.reduce((total, n) => total + n, 0);
}
console.log(sum(1, 2, 3)); // 6
console.log(sum(10, 20)); // 30Practical patterns
Function parameter destructuringWhat is destructuring?A shorthand for pulling specific values out of an object or array into their own variables instead of accessing them one by one.
// Instead of accessing user.name, user.age inside the function:
function greet({ name, age }) {
return `Hello, ${name}! You are ${age}.`;
}
greet({ name: "Alice", age: 25 }); // "Hello, Alice! You are 25."Cloning with property updates
This pattern is extremely common in React for updating state immutably:
const user = { name: "Alice", age: 25, city: "Paris" };
// Create new object with updated age
const updated = { ...user, age: 26 };
console.log(updated); // { name: "Alice", age: 26, city: "Paris" }
console.log(user); // { name: "Alice", age: 25, city: "Paris" } - unchangedSwapping variables
let a = 1;
let b = 2;
[a, b] = [b, a]; // a = 2, b = 1Quick reference
| Pattern | Syntax | What it does |
|---|---|---|
| Object destructuring | const { a, b } = obj | Extract named properties |
| Rename | const { a: x } = obj | Extract a into variable x |
| Default | const { a = 1 } = obj | Fallback if property missing |
| Array destructuring | const [a, b] = arr | Extract by position |
| Rest (array) | const [a, ...rest] = arr | Collect remaining items |
| Rest (object) | const { a, ...rest } = obj | Collect remaining properties |
| Spread (array) | [...arr1, ...arr2] | Merge arrays |
| Spread (object) | { ...obj1, ...obj2 } | Merge objects (shallow) |
| Rest params | function f(...args) | Collect all arguments |