Advanced JavaScript (ES6+)

Destructuring

13 min Lesson 5 of 40

Destructuring

Destructuring is one of ES6's most elegant features. It allows you to extract values from arrays and objects into distinct variables using concise syntax. This lesson covers array destructuring, object destructuring, and advanced patterns that will make your code cleaner and more expressive.

Array Destructuring Basics

Array destructuring unpacks array values into separate variables:

Old Way (Index Access): const colors = ["red", "green", "blue"]; const first = colors[0]; const second = colors[1]; const third = colors[2]; New Way (Destructuring): const colors = ["red", "green", "blue"]; const [first, second, third] = colors; console.log(first); // "red" console.log(second); // "green" console.log(third); // "blue"

You can skip elements you don't need:

const numbers = [1, 2, 3, 4, 5]; // Skip elements with empty slots const [first, , third, , fifth] = numbers; console.log(first); // 1 console.log(third); // 3 console.log(fifth); // 5 // Get only what you need const [a, b] = numbers; // Takes first two elements console.log(a, b); // 1, 2
Tip: Array destructuring works with any iterable, including strings, Sets, and Maps!

Object Destructuring Basics

Object destructuring extracts properties by name:

Old Way (Dot Notation): const user = { name: "John", age: 25, city: "New York" }; const name = user.name; const age = user.age; const city = user.city; New Way (Destructuring): const user = { name: "John", age: 25, city: "New York" }; const { name, age, city } = user; console.log(name); // "John" console.log(age); // 25 console.log(city); // "New York"

Variable names must match property names (unless you rename them):

const product = { id: 123, title: "Laptop", price: 999 }; // Extract specific properties const { title, price } = product; console.log(title); // "Laptop" console.log(price); // 999 // Rename during destructuring const { title: productName, price: productPrice } = product; console.log(productName); // "Laptop" console.log(productPrice); // 999
Key Difference: Array destructuring uses position (order matters), while object destructuring uses property names (order doesn't matter).

Default Values in Destructuring

Provide fallback values for missing properties or elements:

Array with Defaults: const colors = ["red"]; const [first = "black", second = "white", third = "gray"] = colors; console.log(first); // "red" (from array) console.log(second); // "white" (default) console.log(third); // "gray" (default)
Object with Defaults: const user = { name: "John", age: 25 }; const { name, age, city = "Unknown", country = "USA" } = user; console.log(name); // "John" console.log(age); // 25 console.log(city); // "Unknown" (default) console.log(country); // "USA" (default)

Defaults work with renaming:

const settings = { theme: "dark" }; const { theme = "light", fontSize: size = 14, language: lang = "en" } = settings; console.log(theme); // "dark" (from object) console.log(size); // 14 (default, renamed from fontSize) console.log(lang); // "en" (default, renamed from language)

Rest Pattern in Destructuring

The rest operator (...) collects remaining elements:

Rest in Arrays: const numbers = [1, 2, 3, 4, 5]; const [first, second, ...rest] = numbers; console.log(first); // 1 console.log(second); // 2 console.log(rest); // [3, 4, 5]
Rest in Objects: const user = { name: "John", age: 25, city: "New York", country: "USA", email: "john@example.com" }; const { name, age, ...otherInfo } = user; console.log(name); // "John" console.log(age); // 25 console.log(otherInfo); // { city: "New York", country: "USA", email: "john@example.com" }
Important: The rest element must be the last element in destructuring. const [first, ...rest, last] = arr; is invalid!

Nested Destructuring

Destructure nested objects and arrays:

Nested Objects: const user = { name: "John", age: 25, address: { street: "123 Main St", city: "New York", country: "USA" } }; // Destructure nested address const { name, address: { city, country } } = user; console.log(name); // "John" console.log(city); // "New York" console.log(country); // "USA" console.log(address); // ReferenceError: address is not defined
Nested Arrays: const data = [1, [2, 3], [4, [5, 6]]]; const [a, [b, c], [d, [e, f]]] = data; console.log(a); // 1 console.log(b); // 2 console.log(c); // 3 console.log(d); // 4 console.log(e); // 5 console.log(f); // 6
Mixed Nested Destructuring: const response = { status: 200, data: { users: [ { id: 1, name: "John" }, { id: 2, name: "Jane" } ] } }; const { status, data: { users: [firstUser, secondUser] } } = response; console.log(status); // 200 console.log(firstUser); // { id: 1, name: "John" } console.log(secondUser); // { id: 2, name: "Jane" }

Destructuring in Function Parameters

One of the most powerful uses of destructuring:

Object Parameters (named parameters): // Old way function createUser(name, age, city, country) { // Easy to mix up parameter order! console.log(name, age, city, country); } createUser("John", 25, "New York", "USA"); // New way with destructuring function createUser({ name, age, city, country }) { console.log(name, age, city, country); } // Order doesn't matter! createUser({ country: "USA", name: "John", city: "New York", age: 25 });

With default values:

function greet({ name = "Guest", greeting = "Hello" } = {}) { console.log(`${greeting}, ${name}!`); } greet({ name: "John" }); // "Hello, John!" greet({ greeting: "Hi" }); // "Hi, Guest!" greet({}); // "Hello, Guest!" greet(); // "Hello, Guest!" (empty object default)

Array parameter destructuring:

function sumFirstTwo([a, b]) { return a + b; } console.log(sumFirstTwo([5, 3, 10, 20])); // 8 (5 + 3) function processCoordinates([x, y, z = 0]) { console.log(`X: ${x}, Y: ${y}, Z: ${z}`); } processCoordinates([10, 20]); // "X: 10, Y: 20, Z: 0" processCoordinates([10, 20, 30]); // "X: 10, Y: 20, Z: 30"

Practical Applications and Patterns

Swapping Variables: let a = 1; let b = 2; [a, b] = [b, a]; // Swap without temp variable console.log(a); // 2 console.log(b); // 1
Returning Multiple Values: function getMinMax(numbers) { return { min: Math.min(...numbers), max: Math.max(...numbers) }; } const { min, max } = getMinMax([5, 2, 8, 1, 9]); console.log(min, max); // 1, 9
Working with Fetch API: fetch("https://api.example.com/user/123") .then(response => response.json()) .then(({ name, email, avatar }) => { console.log(`Name: ${name}`); console.log(`Email: ${email}`); console.log(`Avatar: ${avatar}`); });
Extracting Values from Arrays: const [year, month, day] = "2024-12-25".split("-"); console.log(year, month, day); // "2024", "12", "25" const url = "https://example.com/products/123"; const [, , , category, id] = url.split("/"); console.log(category, id); // "products", "123"
React Props Destructuring (common pattern): // Instead of: function UserCard(props) { return `<h2>${props.name}</h2><p>${props.age}</p>`; } // Use destructuring: function UserCard({ name, age, city = "Unknown" }) { return `<h2>${name}</h2><p>Age: ${age}, City: ${city}</p>`; }
Configuration Options: function initializeApp({ theme = "light", language = "en", notifications = true, analytics = false } = {}) { console.log("Theme:", theme); console.log("Language:", language); console.log("Notifications:", notifications); console.log("Analytics:", analytics); } // Use with partial options initializeApp({ theme: "dark", analytics: true });

Practice Exercise:

Refactor this code using destructuring:

const user = { firstName: "John", lastName: "Doe", age: 25, address: { street: "123 Main St", city: "New York" }, hobbies: ["reading", "coding", "gaming"] }; const firstName = user.firstName; const lastName = user.lastName; const city = user.address.city; const firstHobby = user.hobbies[0]; const secondHobby = user.hobbies[1]; function displayUser(user) { console.log("Name: " + user.firstName + " " + user.lastName); console.log("Age: " + user.age); console.log("City: " + user.address.city); }

Solution:

const user = { firstName: "John", lastName: "Doe", age: 25, address: { street: "123 Main St", city: "New York" }, hobbies: ["reading", "coding", "gaming"] }; // Destructure top-level and nested properties const { firstName, lastName, address: { city }, hobbies: [firstHobby, secondHobby] } = user; // Function parameter destructuring function displayUser({ firstName, lastName, age, address: { city } }) { console.log(`Name: ${firstName} ${lastName}`); console.log(`Age: ${age}`); console.log(`City: ${city}`); } displayUser(user);

Common Patterns in Real Applications

Working with API Responses: async function fetchUserData(userId) { const response = await fetch(`/api/users/${userId}`); const { data: { user, posts }, status, message } = await response.json(); return { user, posts, status, message }; }
State Management (Redux pattern): const state = { user: { name: "John", loggedIn: true }, settings: { theme: "dark", notifications: true }, cart: { items: [], total: 0 } }; const { user: { name, loggedIn }, settings: { theme }, cart: { total } } = state;
Handling Multiple Return Values: function divideWithRemainder(dividend, divisor) { return { quotient: Math.floor(dividend / divisor), remainder: dividend % divisor }; } const { quotient, remainder } = divideWithRemainder(17, 5); console.log(`${quotient} remainder ${remainder}`); // "3 remainder 2"

Summary

In this lesson, you learned:

  • Array destructuring extracts values by position: [a, b, c] = arr
  • Object destructuring extracts values by name: { name, age } = obj
  • Default values provide fallbacks: { name = "Guest" } = obj
  • Rest operator collects remaining elements: { name, ...rest } = obj
  • Nested destructuring accesses deep properties
  • Function parameter destructuring creates named parameters
  • Destructuring makes code more readable and expressive
  • Common patterns: swapping variables, multiple returns, API responses
Next Up: In the next lesson, we'll explore the spread and rest operators in depth - powerful tools for working with arrays and objects!

ES
Edrees Salih
11 hours ago

We are still cooking the magic in the way!