Destructuring extracts values from arrays and objects cleanly. Here's how to use it effectively.
Array Destructuring#
1// Basic array destructuring
2const colors = ['red', 'green', 'blue'];
3const [first, second, third] = colors;
4// first = 'red', second = 'green', third = 'blue'
5
6// Skip elements
7const [primary, , tertiary] = colors;
8// primary = 'red', tertiary = 'blue'
9
10// Rest pattern
11const numbers = [1, 2, 3, 4, 5];
12const [head, ...tail] = numbers;
13// head = 1, tail = [2, 3, 4, 5]
14
15// Default values
16const sparse = [1];
17const [a, b = 10] = sparse;
18// a = 1, b = 10
19
20// Swapping variables
21let x = 1, y = 2;
22[x, y] = [y, x];
23// x = 2, y = 1
24
25// From functions
26function getCoordinates() {
27 return [10, 20];
28}
29const [coordX, coordY] = getCoordinates();Object Destructuring#
1// Basic object destructuring
2const user = { name: 'Alice', age: 30, email: 'alice@example.com' };
3const { name, age } = user;
4// name = 'Alice', age = 30
5
6// Renaming variables
7const { name: userName, age: userAge } = user;
8// userName = 'Alice', userAge = 30
9
10// Default values
11const config = { host: 'localhost' };
12const { host, port = 3000 } = config;
13// host = 'localhost', port = 3000
14
15// Rename with default
16const { port: serverPort = 8080 } = config;
17// serverPort = 8080
18
19// Rest pattern
20const { name: n, ...rest } = user;
21// n = 'Alice', rest = { age: 30, email: 'alice@example.com' }
22
23// Computed property names
24const key = 'name';
25const { [key]: value } = user;
26// value = 'Alice'Nested Destructuring#
1// Nested objects
2const company = {
3 name: 'TechCorp',
4 address: {
5 city: 'San Francisco',
6 country: 'USA',
7 },
8 employees: [
9 { name: 'Alice', role: 'Engineer' },
10 { name: 'Bob', role: 'Designer' },
11 ],
12};
13
14const {
15 name: companyName,
16 address: { city, country },
17} = company;
18// companyName = 'TechCorp', city = 'San Francisco', country = 'USA'
19
20// Nested arrays
21const matrix = [[1, 2], [3, 4], [5, 6]];
22const [[a, b], [c, d]] = matrix;
23// a = 1, b = 2, c = 3, d = 4
24
25// Mixed nesting
26const {
27 employees: [firstEmployee, secondEmployee],
28} = company;
29// firstEmployee = { name: 'Alice', role: 'Engineer' }
30
31// Deep extraction
32const {
33 employees: [{ name: firstName }],
34} = company;
35// firstName = 'Alice'Function Parameters#
1// Object parameters
2function createUser({ name, age, email = 'default@email.com' }) {
3 return { name, age, email };
4}
5
6createUser({ name: 'Alice', age: 30 });
7
8// With defaults for entire parameter
9function greet({ name = 'Guest', greeting = 'Hello' } = {}) {
10 return `${greeting}, ${name}!`;
11}
12
13greet(); // 'Hello, Guest!'
14greet({ name: 'Alice' }); // 'Hello, Alice!'
15
16// Array parameters
17function sum([first, second, ...rest]) {
18 return first + second + rest.reduce((a, b) => a + b, 0);
19}
20
21sum([1, 2, 3, 4]); // 10
22
23// React component props
24function UserCard({ name, avatar, role = 'User' }) {
25 return (
26 <div>
27 <img src={avatar} alt={name} />
28 <h2>{name}</h2>
29 <span>{role}</span>
30 </div>
31 );
32}Advanced Patterns#
1// Multiple return values
2function getMinMax(arr) {
3 return {
4 min: Math.min(...arr),
5 max: Math.max(...arr),
6 };
7}
8
9const { min, max } = getMinMax([1, 5, 3, 9, 2]);
10
11// Optional chaining with destructuring
12const data = { user: null };
13const { user: { name } = {} } = data;
14// name = undefined (no error)
15
16// Destructuring in loops
17const users = [
18 { id: 1, name: 'Alice' },
19 { id: 2, name: 'Bob' },
20];
21
22for (const { id, name } of users) {
23 console.log(`${id}: ${name}`);
24}
25
26// Map entries
27const map = new Map([
28 ['a', 1],
29 ['b', 2],
30]);
31
32for (const [key, value] of map) {
33 console.log(`${key}: ${value}`);
34}
35
36// Regex groups
37const regex = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
38const match = regex.exec('2024-01-15');
39const { groups: { year, month, day } } = match;Practical Examples#
1// API response handling
2async function fetchUser(id) {
3 const response = await fetch(`/api/users/${id}`);
4 const { data: user, meta: { timestamp } } = await response.json();
5 return { user, timestamp };
6}
7
8// Event handling
9document.addEventListener('click', ({ target, clientX, clientY }) => {
10 console.log(`Clicked ${target.tagName} at (${clientX}, ${clientY})`);
11});
12
13// Module imports
14import { useState, useEffect, useCallback } from 'react';
15
16// Configuration objects
17function initApp({
18 port = 3000,
19 host = 'localhost',
20 debug = false,
21 database: {
22 url = 'mongodb://localhost',
23 name = 'mydb',
24 } = {},
25} = {}) {
26 console.log(`Starting on ${host}:${port}`);
27 console.log(`Database: ${url}/${name}`);
28 console.log(`Debug: ${debug}`);
29}
30
31initApp({
32 port: 8080,
33 database: { name: 'production' },
34});
35
36// React hooks
37function useForm(initialValues) {
38 const [values, setValues] = useState(initialValues);
39
40 const handleChange = ({ target: { name, value } }) => {
41 setValues(prev => ({ ...prev, [name]: value }));
42 };
43
44 return { values, handleChange };
45}Combining with Spread#
1// Clone and modify
2const original = { a: 1, b: 2, c: 3 };
3const { a, ...withoutA } = original;
4const modified = { ...withoutA, d: 4 };
5// { b: 2, c: 3, d: 4 }
6
7// Merge with override
8const defaults = { theme: 'light', lang: 'en' };
9const userPrefs = { theme: 'dark' };
10const { theme, lang } = { ...defaults, ...userPrefs };
11// theme = 'dark', lang = 'en'
12
13// Pick properties
14function pick(obj, keys) {
15 return keys.reduce((acc, key) => {
16 if (key in obj) acc[key] = obj[key];
17 return acc;
18 }, {});
19}
20
21// Omit properties
22function omit(obj, keys) {
23 const keysSet = new Set(keys);
24 return Object.fromEntries(
25 Object.entries(obj).filter(([key]) => !keysSet.has(key))
26 );
27}
28
29// Usage
30const user = { id: 1, name: 'Alice', password: 'secret' };
31const safeUser = omit(user, ['password']);
32// { id: 1, name: 'Alice' }Error Handling#
1// Safe destructuring with defaults
2function processData(data) {
3 const {
4 items = [],
5 meta: { page = 1, total = 0 } = {},
6 } = data || {};
7
8 return { items, page, total };
9}
10
11// Handles: null, undefined, missing properties
12processData(null); // { items: [], page: 1, total: 0 }
13processData({}); // { items: [], page: 1, total: 0 }
14processData({ items: [1, 2] }); // { items: [1, 2], page: 1, total: 0 }
15
16// Try-catch for complex cases
17function safeDestructure(obj, path, defaultValue) {
18 try {
19 const keys = path.split('.');
20 let result = obj;
21 for (const key of keys) {
22 result = result[key];
23 }
24 return result ?? defaultValue;
25 } catch {
26 return defaultValue;
27 }
28}TypeScript Destructuring#
1// Typed destructuring
2interface User {
3 name: string;
4 age: number;
5 email?: string;
6}
7
8function greet({ name, age }: User): string {
9 return `Hello ${name}, you are ${age}`;
10}
11
12// With defaults
13function createUser({
14 name,
15 age,
16 email = 'default@email.com',
17}: Partial<User> & { name: string }) {
18 return { name, age, email };
19}
20
21// Array types
22function processCoords([x, y]: [number, number]): number {
23 return x + y;
24}
25
26// Rest with types
27function logAll({ name, ...rest }: User & Record<string, unknown>) {
28 console.log(name, rest);
29}Best Practices#
Readability:
✓ Keep destructuring shallow when possible
✓ Use meaningful variable names
✓ Add defaults for optional values
✓ Break complex patterns into steps
Safety:
✓ Provide defaults for nested objects
✓ Use || {} for potentially undefined
✓ Consider optional chaining
✓ Validate before destructuring
Performance:
✓ Destructure only what you need
✓ Avoid repeated destructuring
✓ Use rest sparingly in hot paths
✓ Profile complex patterns
Avoid:
✗ Deeply nested destructuring
✗ Destructuring in loops (sometimes)
✗ Confusing rename chains
✗ Missing defaults for optional props
Conclusion#
Destructuring makes code cleaner and more expressive. Use array destructuring for ordered data, object destructuring for named properties, and combine with defaults for safety. Keep patterns simple and readable, especially with nested structures.