Skip to main content

Command Palette

Search for a command to run...

Destructuring in JavaScript

Updated
10 min read

Destructuring is just a shorter way to pull values out of arrays and objects. That's it.


What Destructuring Actually Means

Imagine you get a box with three items inside, a book, a pen, and a notebook. Normally, you'd open the box and take each item out one at a time, placing each one somewhere useful.

Destructuring in JavaScript does the same thing with arrays and objects. It lets you unpack values from a collection and put them into individual variables, all in one line.

Before destructuring existed, you'd write something like this to grab values from an object:

const person = { name: "Priya", age: 28, city: "Mumbai" };

const name = person.name;
const age  = person.age;
const city = person.city;

console.log(name); // "Priya"
console.log(age);  // 28
console.log(city); // "Mumbai"

Three separate lines just to pull three values out. With destructuring, you do all of that in one line:

const { name, age, city } = person;

console.log(name); // "Priya"
console.log(age);  // 28
console.log(city); // "Mumbai"

Same result. Less typing. Easier to read. That's what destructuring gives you.


Destructuring Arrays

With arrays, destructuring works by position. The first variable gets the first element, the second variable gets the second element, and so on.

const colors = ["red", "green", "blue"];

// Without destructuring
const first  = colors[0]; // "red"
const second = colors[1]; // "green"
const third  = colors[2]; // "blue"

// With destructuring
const [first, second, third] = colors;

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

The square brackets on the left mirror the shape of the array on the right. You're telling JavaScript: "give me the items in this array and put them into these variables, in order."

Skipping Elements

You don't have to grab every element. Leave a gap with a comma to skip positions you don't need:

const scores = [95, 72, 88, 61, 99];

const [highest, , third] = scores;

console.log(highest); // 95
console.log(third);   // 88
// second score (72) was skipped

Grabbing the Rest

You can collect all remaining elements into a separate array using the rest syntax (...):

const [head, ...tail] = [10, 20, 30, 40, 50];

console.log(head); // 10
console.log(tail); // [20, 30, 40, 50]

This is useful when you know you want the first item separately, and everything else together.

Swapping Variables

One of the neatest tricks with array destructuring, swapping two variables without a temp variable:

let a = 1;
let b = 2;

// Old way — needs a third variable
let temp = a;
a = b;
b = temp;

// Destructuring way — clean and direct
[a, b] = [b, a];

console.log(a); // 2
console.log(b); // 1

Destructuring Objects

Object destructuring works by name, not position. The variable name on the left has to match the property name in the object.

const book = {
  title: "JavaScript: The Good Parts",
  author: "Douglas Crockford",
  year: 2008,
  pages: 176
};

// Without destructuring — repetitive
const title  = book.title;
const author = book.author;
const pages  = book.pages;

// With destructuring — clean
const { title, author, pages } = book;

console.log(title);  // "JavaScript: The Good Parts"
console.log(author); // "Douglas Crockford"
console.log(pages);  // 176

You're not forced to grab every property. Just name the ones you actually need.

Renaming While Destructuring

Sometimes the property name from an object doesn't fit what you want to call it in your code. You can rename it during destructuring using a colon:

const user = { firstName: "Arjun", lastName: "Mehta", userAge: 32 };

const { firstName: name, userAge: age } = user;

console.log(name); // "Arjun"
console.log(age);  // 32
// firstName and userAge no longer exist as variable names here

The syntax reads as: "take firstName from the object, and call it name here."

Nested Object Destructuring

If the object has objects inside it, you can destructure those too, all in one go:

const employee = {
  name: "Zara",
  role: "Developer",
  address: {
    city: "Bangalore",
    pincode: "560001"
  }
};

// Old way
const city    = employee.address.city;
const pincode = employee.address.pincode;

// Nested destructuring
const { name, address: { city, pincode } } = employee;

console.log(name);    // "Zara"
console.log(city);    // "Bangalore"
console.log(pincode); // "560001"

Note that address itself doesn't become a variable here, it's used as a path to get to city and pincode.


Default Values

What happens when a property doesn't exist in the object, or an element isn't in the array? Normally you'd get undefined. With destructuring, you can set a default value that's used as a fallback:

const settings = { theme: "dark" };

const { theme, fontSize = 16, language = "en" } = settings;

console.log(theme);    // "dark"     — came from the object
console.log(fontSize); // 16         — default, because it wasn't in the object
console.log(language); // "en"       — default, because it wasn't in the object

The default only kicks in when the value is undefined. If the property exists in the object, even if it's null or 0, the default is ignored.

const { count = 10 } = { count: 0 };

console.log(count); // 0 — not 10, because 0 was explicitly set

This is a subtle but important detail. 0 is a real value, so the default doesn't apply.

Defaults work in array destructuring too:

const [x = 5, y = 10] = [1];

console.log(x); // 1  — came from array
console.log(y); // 10 — default, because there's no second element

Destructuring in Function Parameters

This is where things get really useful day to day. Instead of receiving an entire object and then picking values off it inside the function, you can destructure right in the parameter list:

// Without parameter destructuring — repetitive
function displayUser(user) {
  console.log(user.name);
  console.log(user.email);
  console.log(user.age);
}

// With parameter destructuring — clean
function displayUser({ name, email, age }) {
  console.log(name);
  console.log(email);
  console.log(age);
}

const user = { name: "Priya", email: "priya@example.com", age: 28 };
displayUser(user);

Same result. But the second version immediately tells you, just by reading the function signature, exactly which properties this function uses. You don't have to read the body to know what it needs.

You can combine this with default values too:

function createButton({ label = "Click Me", color = "blue", size = "medium" } = {}) {
  return `<button style="color:\({color}; font-size:\){size}">${label}</button>`;
}

createButton({ label: "Submit", color: "green" });
// uses default size: "medium"

createButton();
// uses all defaults — the = {} handles being called with no argument

Real-World Examples

Destructuring an API Response

API responses are usually deeply nested objects. Destructuring makes pulling out exactly what you need much less painful:

// Typical API response
const response = {
  status: 200,
  data: {
    user: {
      id: 42,
      name: "Arjun Sharma",
      email: "arjun@example.com",
      subscription: {
        plan: "pro",
        expires: "2026-12-31"
      }
    }
  }
};

// Reach in and grab exactly what you need
const {
  data: {
    user: {
      name,
      email,
      subscription: { plan }
    }
  }
} = response;

console.log(name);  // "Arjun Sharma"
console.log(email); // "arjun@example.com"
console.log(plan);  // "pro"

Destructuring in a Loop

When you're looping over an array of objects, you can destructure inside the loop:

const students = [
  { name: "Priya",  grade: "A" },
  { name: "Arjun",  grade: "B" },
  { name: "Zara",   grade: "A" }
];

for (const { name, grade } of students) {
  console.log(`\({name}: \){grade}`);
}
// Priya: A
// Arjun: B
// Zara: A

Instead of writing student.name and student.grade inside the loop, you pull them out right where the loop starts.

Returning Multiple Values from a Function

JavaScript functions can only return one value. But that value can be an array or object, and destructuring makes receiving multiple values feel natural:

function getMinMax(numbers) {
  return {
    min: Math.min(...numbers),
    max: Math.max(...numbers)
  };
}

const { min, max } = getMinMax([5, 2, 9, 1, 7]);

console.log(min); // 1
console.log(max); // 9

Or with an array:

function splitName(fullName) {
  return fullName.split(" ");
}

const [firstName, lastName] = splitName("Priya Sharma");

console.log(firstName); // "Priya"
console.log(lastName);  // "Sharma"

Before vs After: The Readability Difference

Here's the same task written without and with destructuring, so you can feel the difference clearly:

// Without destructuring
function showOrderSummary(order) {
  const customerName = order.customer.name;
  const customerCity = order.customer.address.city;
  const itemName     = order.item.name;
  const itemPrice    = order.item.price;
  const itemQuantity = order.item.quantity;

  console.log(`\({customerName} from \){customerCity}`);
  console.log(`\({itemQuantity}x \){itemName} — ₹${itemPrice * itemQuantity}`);
}

// With destructuring
function showOrderSummary(order) {
  const { customer: { name, address: { city } }, item: { name: itemName, price, quantity } } = order;

  console.log(`\({name} from \){city}`);
  console.log(`\({quantity}x \){itemName} — ₹${price * quantity}`);
}

The second version takes a moment to read the first line, but from that point on the function body is clean, just the logic, no order.this.that.other.


Benefits of Destructuring

Less repetition. You stop writing object.property over and over and just use the variable directly.

Clearer intent. When a function signature shows { name, email, role }, you know immediately what it needs — without reading the body.

Fewer mistakes. Pulling values into named variables means you're less likely to mistype user.naem somewhere in the code.

Cleaner loops. Destructuring in for...of loops removes the need for item.prop access on every iteration.

Natural multiple returns. Returning an object or array and immediately destructuring it feels like getting multiple return values from a function.


Key Takeaways

  • Destructuring is a shorthand for unpacking values from arrays and objects into individual variables.

  • Array destructuring works by position, first variable gets first element.

  • Object destructuring works by name, variable name must match property name.

  • You can rename properties during object destructuring using propertyName: newName.

  • You can set default values for variables that might be missing, defaults only apply when the value is undefined.

  • Destructuring in function parameters makes it immediately clear what a function expects.

  • You can skip array elements with commas, and collect the rest with ...rest.

  • Nested objects can be destructured in one line, no need to go level by level.


Quick Reference

// Array destructuring
const [a, b, c] = [1, 2, 3];
const [first, , third] = [1, 2, 3];     // skip middle
const [head, ...tail] = [1, 2, 3, 4];   // head=1, tail=[2,3,4]
[a, b] = [b, a];                         // swap variables

// Object destructuring
const { name, age } = person;
const { name: fullName } = person;       // rename
const { name, score = 0 } = player;     // default value

// Nested
const { address: { city } } = user;

// In function params
function greet({ name, age = 18 }) { ... }

// Array defaults
const [x = 0, y = 0] = [5];             // x=5, y=0

// In loops
for (const { name, email } of users) { ... }

// Multiple return values
const { min, max } = getMinMax(numbers);
const [first, last] = splitName("Priya Sharma");

Once you start using destructuring, going back feels like putting each grocery item away one by one when you could have tipped the whole bag onto the counter at once.