Destructuring in JavaScript: Write Less, Read More

Search for a command to run...

No comments yet. Be the first to comment.
Introduction If you've ever built something with vanilla JavaScript and had to update the UI frequently, you already know the pain. You call document.getElementById, change some text, update a class,
Introduction If you've ever installed and tried out Linux after seeing a cool hacking sequence in a sci-fi movie, you know that opening it feels like stepping into a strange city with many roads named

Introduction Most JavaScript confusion around this comes from one wrong assumption: that this depends on where a function is defined. It doesn't. It depends on who called the function. That one shift

Introduction JavaScript gives you objects and arrays out of the box, and for a long time those two were the default answer to almost every data storage problem. Objects for key-value pairs, arrays for

Most JavaScript codebases are full of code like this:
const user = { name: "Sara", age: 28, city: "Mumbai" };
const name = user.name;
const age = user.age;
const city = user.city;
Three separate lines to pull three values out of one object. It works, but it's tedious. Destructuring is the cleaner way to do the same thing.
Destructuring is a syntax that lets you unpack values from arrays or properties from objects into individual variables, all in one line. The word sounds more complicated than the concept. You're just telling JavaScript: "grab these specific things and give them their own names."
It showed up in ES6 (2015) and has become one of those features you use constantly once you know it.
With arrays, destructuring works by position. The first variable gets the first element, the second gets the second, and so on.
Before:
const colors = ["red", "green", "blue"];
const first = colors[0];
const second = colors[1];
const third = colors[2];
After:
const colors = ["red", "green", "blue"];
const [first, second, third] = colors;
Same result, less noise.
You can skip positions you don't care about using commas:
const [, second, , fourth] = [10, 20, 30, 40];
console.log(second); // 20
console.log(fourth); // 40
You can grab the first few items and collect the rest into a new array:
const [head, ...tail] = [1, 2, 3, 4, 5];
console.log(head); // 1
console.log(tail); // [2, 3, 4, 5]
The above example makes use of the rest operator. If you do not know about it, checkout this other blog post I wrote on Spread & Rest Operators in JavaScript.
With objects, you match by property name, not position. The variable name has to match the key you want to extract.
Before:
const product = { title: "Notebook", price: 120, stock: 50 };
const title = product.title;
const price = product.price;
const stock = product.stock;
After:
const { title, price, stock } = product;
Same three variables, one line.
If you want a different variable name than the property key:
const { title: productName, price: cost } = product;
console.log(productName); // "Notebook"
console.log(cost); // 120
The syntax reads as "extract title, but call it productName."
Objects inside objects work too, you just nest the destructuring syntax:
const order = {
id: 101,
customer: {
name: "Raj",
email: "raj@example.com"
}
};
const { customer: { name, email } } = order;
console.log(name); // "Raj"
console.log(email); // "raj@example.com"
What happens if the property you're trying to extract doesn't exist? Without a default, you get undefined. With a default, you get a fallback.
const settings = { theme: "dark" };
const { theme, language = "en" } = settings;
console.log(theme); // "dark"
console.log(language); // "en"
language wasn't in settings, so the default kicked in. This works for arrays too:
const [a = 0, b = 0] = [5];
console.log(a); // 5
console.log(b); // 0
Defaults only apply when the value is undefined, not when it's null or 0 or an empty string.
This is probably the most common use. Instead of pulling properties out at the start of every function:
// Before
function greet(user) {
const name = user.name;
const age = user.age;
console.log(`\({name} is \){age} years old`);
}
// After
function greet({ name, age }) {
console.log(`\({name} is \){age} years old`);
}
The function signature now tells you exactly what it needs. That's a real improvement when you're reading unfamiliar code.
Without destructuring, swapping two variables needs a temp:
let x = 1, y = 2;
let temp = x;
x = y;
y = temp;
With destructuring:
let x = 1, y = 2;
[x, y] = [y, x];
Functions can only return one thing, but that thing can be an array or object. Destructuring makes unpacking the result clean:
function getMinMax(arr) {
return { min: Math.min(...arr), max: Math.max(...arr) };
}
const { min, max } = getMinMax([3, 1, 7, 2, 9]);
console.log(min); // 1
console.log(max); // 9
The real benefit isn't that destructuring saves a few lines. It's that code becomes easier to scan. When you see const { name, age } = user at the top of a function, you immediately know what data that function works with. You don't have to trace through user.this and user.that scattered across 20 lines.
It also reduces the chance of typos. Writing user.nmae is easy to miss. Destructuring once at the top and using name everywhere after that gives you one place where a typo can happen instead of many.
That said, don't destructure everything just because you can. For a one-off property access, user.name is perfectly readable. Destructuring earns its place when you're using multiple properties, passing them into functions, or cleaning up function parameters.