Destructuring is a syntax for extracting values from arrays or properties from objects into distinct variables in one statement.
Array destructuring:
Extract elements by position using square brackets. Can skip elements with empty commas. Use rest operator to collect remaining elements. Supports default values for missing elements. Works with any iterable including strings.
Object destructuring:
Extract properties by name using curly braces. Can rename variables with colon syntax. Supports default values for undefined properties. Can destructure nested objects. Use rest operator to collect remaining properties.
Advanced patterns:
Nested destructuring for deeply nested data. Destructuring in function parameters for clean APIs. Combining with default values for robust code. Using computed property names. Destructuring from function returns.
Common use cases:
Swapping variables without temp. Extracting values from API responses. Function parameters with options object. Working with arrays of data. Multiple return values from functions.
Benefits:
Cleaner code with less repetition. More readable variable extraction. Natural fit for modern JavaScript patterns. Essential for React and modern frameworks.
Gotchas:
Destructuring undefined or null throws error. Default values only work with undefined, not null. Creating new object when destructuring requires parentheses. Variable must be in scope for assignment destructuring.
Understanding destructuring thoroughly shows mastery of modern JavaScript syntax and patterns.
Example code
// ARRAY DESTRUCTURING
const arr = [1, 2, 3, 4, 5];
// Basic extraction
const [first, second] = arr;
console.log(first); // 1
console.log(second); // 2
// Skip elements
const [a, , c] = arr;
console.log(a); // 1
console.log(c); // 3
// Rest operator
const [head, ...tail] = arr;
console.log(head); // 1
console.log(tail); // [2, 3, 4, 5]
// Default values
const [x, y, z = 10] = [1, 2];
console.log(z); // 10
// Swapping variables
let num1 = 10;
let num2 = 20;
[num1, num2] = [num2, num1];
console.log(num1); // 20
console.log(num2); // 10
// Nested arrays
const nested = [1, [2, 3], 4];
const [n1, [n2, n3]] = nested;
console.log(n2); // 2
// String destructuring
const [char1, char2] = 'hello';
console.log(char1); // 'h'
// OBJECT DESTRUCTURING
const user = {
name: 'John',
age: 30,
email: 'john@example.com'
};
// Basic extraction
const {name, age} = user;
console.log(name); // 'John'
console.log(age); // 30
// Rename variables
const {name: userName, age: userAge} = user;
console.log(userName); // 'John'
// Default values
const {email, phone = 'N/A'} = user;
console.log(phone); // 'N/A'
// Rest operator
const {name: n, ...others} = user;
console.log(others); // {age: 30, email: '...'}
// Nested objects
const person = {
name: 'John',
address: {
city: 'NYC',
zip: '10001'
}
};
const {
name: personName,
address: {city, zip}
} = person;
console.log(city); // 'NYC'
// FUNCTION PARAMETERS
// Object destructuring in params
function greet({name, age, country = 'USA'}) {
console.log(`${name}, ${age}, from ${country}`);
}
greet({name: 'John', age: 30});
// 'John, 30, from USA'
// Array destructuring in params
function sum([a, b]) {
return a + b;
}
console.log(sum([5, 3])); // 8
// ADVANCED PATTERNS
// Computed property names
const key = 'name';
const {[key]: value} = {name: 'John'};
console.log(value); // 'John'
// Destructure and keep original
const data = {x: 1, y: 2};
const {x, y, ...copy} = data;
console.log(copy); // {x: 1, y: 2}
// Multiple returns from function
function getUser() {
return {
name: 'John',
age: 30,
email: 'john@example.com'
};
}
const {name: n2, email: e} = getUser();
// Array method returns
function getCoordinates() {
return [10, 20];
}
const [x2, y2] = getCoordinates();
// PRACTICAL EXAMPLES
// API response
const response = {
data: {
user: {
id: 1,
name: 'John',
profile: {
avatar: 'url',
bio: 'text'
}
}
},
status: 200
};
const {
data: {
user: {
name: userName2,
profile: {avatar}
}
},
status
} = response;
console.log(userName2, avatar, status);
// React props
function Component({title, count = 0, onClick}) {
return `${title}: ${count}`;
}
// Array methods
const users = [
{name: 'John', age: 30},
{name: 'Jane', age: 25}
];
users.forEach(({name, age}) => {
console.log(name, age);
});
const names = users.map(({name}) => name);
// For...of with destructuring
for (const {name, age} of users) {
console.log(name, age);
}
// Object.entries
const obj = {a: 1, b: 2, c: 3};
for (const [key, value] of Object.entries(obj)) {
console.log(key, value);
}
// GOTCHAS
// Error: destructuring undefined/null
// const {x} = undefined; // TypeError!
// const {y} = null; // TypeError!
// Safe with default
const {x: x3} = undefined || {}; // OK
// Assignment destructuring needs parentheses
let name2, age2;
({name: name2, age: age2} = {name: 'John', age: 30});
// Parentheses required!
// Default only for undefined
const {val = 10} = {val: 0};
console.log(val); // 0 (not 10)
const {val2 = 10} = {val2: null};
console.log(val2); // null (not 10)