JavaScript Destructuring

Extracting Data Elegantly

2026-02-01

Explanation

What is Destructuring?

Destructuring is a syntax for extracting values from arrays and properties from objects into distinct variables. It makes code cleaner and more readable.

Key Concepts

  • Array Destructuring: Extract by position
  • Object Destructuring: Extract by property name
  • Default Values: Fallbacks for missing values
  • Rest Pattern: Collect remaining items
  • Nested Destructuring: Extract from nested structures

Demonstration

Example 1: Array Destructuring

// Basic array destructuring
const colors = ['red', 'green', 'blue'];
const [first, second, third] = colors;

console.log(first);   // 'red'
console.log(second);  // 'green'
console.log(third);   // 'blue'

// Skip elements
const [primary, , tertiary] = colors;
console.log(primary);   // 'red'
console.log(tertiary);  // 'blue'

// Default values
const [a, b, c, d = 'yellow'] = colors;
console.log(d);  // 'yellow'

// Rest pattern
const numbers = [1, 2, 3, 4, 5];
const [head, ...tail] = numbers;

console.log(head);  // 1
console.log(tail);  // [2, 3, 4, 5]

// Swapping variables
let x = 1;
let y = 2;
[x, y] = [y, x];
console.log(x, y);  // 2, 1

// From function returns
function getCoordinates() {
    return [10, 20];
}

const [coordX, coordY] = getCoordinates();
console.log(coordX, coordY);  // 10, 20

Example 2: Object Destructuring

// Basic object destructuring
const user = {
    name: 'Arthur',
    email: 'art@bpc.com',
    role: 'admin'
};

const { name, email, role } = user;
console.log(name);   // 'Arthur'
console.log(email);  // 'art@bpc.com'

// Rename variables
const { name: userName, email: userEmail } = user;
console.log(userName);   // 'Arthur'
console.log(userEmail);  // 'art@bpc.com'

// Default values
const { name: n, age = 30 } = user;
console.log(n);    // 'Arthur'
console.log(age);  // 30

// Rename with default
const { status: userStatus = 'active' } = user;
console.log(userStatus);  // 'active'

// Rest pattern
const { name: extractedName, ...rest } = user;
console.log(extractedName);  // 'Arthur'
console.log(rest);  // { email: 'art@bpc.com', role: 'admin' }

// Nested destructuring
const company = {
    name: 'Big Poppa Code',
    address: {
        city: 'New York',
        country: 'USA'
    }
};

const { address: { city, country } } = company;
console.log(city);     // 'New York'
console.log(country);  // 'USA'

Example 3: Function Parameters

// Destructuring in function parameters
function createUser({ name, email, role = 'user' }) {
    return { id: Date.now(), name, email, role };
}

const newUser = createUser({
    name: 'Sarah',
    email: 'sarah@example.com'
});
console.log(newUser);

// Array destructuring in parameters
function sum([a, b, c = 0]) {
    return a + b + c;
}

console.log(sum([1, 2]));     // 3
console.log(sum([1, 2, 3]));  // 6

// Combined with rest
function logFirst(first, ...rest) {
    console.log('First:', first);
    console.log('Rest:', rest);
}

logFirst(1, 2, 3, 4);
// First: 1
// Rest: [2, 3, 4]

// Real-world: React component props
function UserCard({ user, onDelete, className = '' }) {
    return (
        <div className={`user-card ${className}`}>
            <h2>{user.name}</h2>
            <button onClick={() => onDelete(user.id)}>Delete</button>
        </div>
    );
}

// Express route handler
app.get('/users/:id', ({ params: { id }, query }, res) => {
    res.json({ userId: id, query });
});

Example 4: Complex Patterns

// Deeply nested destructuring
const response = {
    data: {
        user: {
            id: 1,
            profile: {
                name: 'Arthur',
                avatar: 'url'
            }
        }
    },
    meta: {
        status: 200
    }
};

const {
    data: {
        user: {
            id,
            profile: { name, avatar }
        }
    },
    meta: { status }
} = response;

console.log(id, name, status);  // 1, 'Arthur', 200

// Mixed array and object
const apiResponse = {
    results: [
        { id: 1, title: 'Post 1' },
        { id: 2, title: 'Post 2' }
    ],
    total: 2
};

const { results: [firstPost, secondPost], total } = apiResponse;
console.log(firstPost.title);  // 'Post 1'

// Dynamic key destructuring
const key = 'name';
const obj = { name: 'Arthur', age: 30 };
const { [key]: value } = obj;
console.log(value);  // 'Arthur'

// Default function for missing property
const getUser = (user) => {
    const {
        name,
        greet = () => `Hello, ${name}`
    } = user;

    return greet();
};

console.log(getUser({ name: 'Arthur' }));  // Hello, Arthur

Example 5: Practical Use Cases

// Import specific exports
import { useState, useEffect, useRef } from 'react';

// API response handling
async function fetchUser(id) {
    const response = await fetch(`/api/users/${id}`);
    const { data: user, error } = await response.json();

    if (error) throw new Error(error);
    return user;
}

// Configuration with defaults
function setupServer({
    port = 3000,
    host = 'localhost',
    ssl = false,
    routes = []
} = {}) {
    console.log(`Server: ${host}:${port}, SSL: ${ssl}`);
    return { port, host, ssl, routes };
}

setupServer();  // Uses all defaults
setupServer({ port: 8080 });  // Override port

// Event handling
document.addEventListener('click', ({ target, clientX, clientY }) => {
    console.log(`Clicked ${target.tagName} at ${clientX}, ${clientY}`);
});

// Array method callbacks
const users = [
    { name: 'Arthur', age: 30 },
    { name: 'Sarah', age: 25 }
];

const names = users.map(({ name }) => name);
const adults = users.filter(({ age }) => age >= 18);
const totalAge = users.reduce((sum, { age }) => sum + age, 0);

// State management
const [state, setState] = useState({ count: 0, loading: false });
const { count, loading } = state;

Key Takeaways:

  • Destructuring extracts values from arrays/objects
  • Use defaults for missing values
  • Rest pattern collects remaining items
  • Works great with function parameters
  • Simplifies working with API responses

Imitation

Challenge 1: Parse API Response

Task: Extract specific data from a complex API response.

const response = {
    status: 'success',
    data: {
        users: [
            { id: 1, name: 'Alice', posts: [{ title: 'Hello' }] },
            { id: 2, name: 'Bob', posts: [] }
        ],
        pagination: {
            page: 1,
            total: 10
        }
    }
};

Solution

const {
    status,
    data: {
        users: [
            { name: firstName, posts: [firstPost = {}] = [] },
            { name: secondName }
        ],
        pagination: { page, total }
    }
} = response;

console.log(status);      // 'success'
console.log(firstName);   // 'Alice'
console.log(firstPost.title);  // 'Hello'
console.log(secondName);  // 'Bob'
console.log(page, total); // 1, 10

// Or more safely with optional chaining
const { data } = response;
const firstUser = data?.users?.[0];
const firstUserFirstPost = firstUser?.posts?.[0]?.title ?? 'No posts';

Challenge 2: Create Config Parser

Task: Write a function that accepts configuration with deep defaults.

Solution

function createConfig({
    app: {
        name = 'MyApp',
        version = '1.0.0'
    } = {},
    server: {
        port = 3000,
        host = 'localhost',
        ssl: {
            enabled = false,
            cert = null,
            key = null
        } = {}
    } = {},
    database: {
        host: dbHost = 'localhost',
        port: dbPort = 5432,
        name: dbName = 'app'
    } = {},
    features = []
} = {}) {
    return {
        app: { name, version },
        server: { port, host, ssl: { enabled, cert, key } },
        database: { host: dbHost, port: dbPort, name: dbName },
        features
    };
}

// All defaults
console.log(createConfig());

// Partial override
console.log(createConfig({
    server: { port: 8080 },
    database: { name: 'production' }
}));


Practice

Exercise 1: State Reducer

Difficulty: Intermediate

Create a reducer function that uses destructuring to handle different action types cleanly.

Exercise 2: Query Parser

Difficulty: Advanced

Build a URL query string parser that returns a destructurable object with typed values.


Summary

What you learned:

  • Array and object destructuring
  • Default values and renaming
  • Rest pattern for collecting items
  • Nested destructuring
  • Function parameter destructuring

Next Steps:

  • Read: Spread and Rest
  • Practice: Refactor code to use destructuring
  • Explore: Optional chaining with destructuring

Resources