Destructuring provides a simple yet effective way of creating variables out of pieces of an array, or properties of an object—this approach usually allows for better and more understandable code.
In JavaScript (and other programming languages) we often work with groups of data like Array and Object. The way of accessing this data is usually through the means of an index for arrays, and a property for objects—but have you ever found yourself having to access the same exact piece of data over and over in your code, to the point where it became harder and harder to understand?
Code clarity is vital when working with teams and for future-proofing your work. Look at the following pieces of code.
//--- Base example
if (users[0].capabilities[0].type === 'edit' && users[0].active)
//--- By hand
const user = users[0]
const active = user.active
const canEdit = user.capabilities[0].type
if (canEdit === 'edit' && active)
//--- With destructuring
const [{ active, capabilities: [{ type: canEdit }] }] = users
if (canEdit === 'edit' && active)
Even though there’s more lines of code, the second example is way clearer and will probably be easier to decipher for anyone else on the team when they look at this particular piece of code. The last example is created with nested destructuring of both an object and a nested array, and is what we will be looking at today.
Destructuring provides a simple yet effective way of creating variables out of pieces of an array, or properties of an object—this approach usually allows for better and more understandable code.
Disclaimer: This article is intended for people that are taking a first approach to the destructuring assignment syntax and having a hard time understanding it. I will only cover the basics around the capabilities that this feature gives us. For more in-depth examples and information, I recommend reading through the examples at the MDN Destructuring assignment page.
const people = ['Karen', 'Bob']`
sendItem(people[0], 'chocs')`
sendItem(people[1], 'coal')`
At first glance, the code above is sort of clear. For some reason, whoever is on index 0 seems to get the good item, while the person on index 1 is only getting a lump of coal.
Maybe we could rewrite the code to be a little clearer.
const people = ['Karen', 'Bob']
const bestFriend = people[0]
const archEnemy = people[1]
sendItem(bestFriend, 'chocs')
sendItem(archEnemy, 'coal')
Now that we have declared some variables that more accurately describe what the indexes of 0 and 1 mean, the code becomes easier to read and understand. However, you can start to see a little verbosity around where we are declaring both the constants.
Right now it’s not a big deal, since it’s only two people that we need to extract from the array. But what if it was 5 or 10? Due to this need, the destructuring syntax came to make our lives better in ES6.
Let’s approach the earlier example using this syntax.
const people = ['Karen', 'Bob']
const [bestFriend, archEnemy] = people
sendItem(bestFriend, 'chocs')
sendItem(archEnemy, 'coal')
This syntax can be very daunting at first, but think back to the days of high school when you were learning algebra, and how much you hated it, and how you could have two sides to an equation.
You already know how to declare an array, so if I told you:
const people = [bestFriend, archEnemy]
That makes perfect sense, right? The variable on the left is assigned the contents on the right.
If we invert the previous statement we would get:
[bestFriend, archEnemy] = const people
Hopefully at this time you’re starting to get that AHA moment of insight. If we look at the previous example, one thing looks out of place right away. We know for a fact in JavaScript we can not set the keyword const to declare a variable on the right side of an assignment. Also, we already have a people array declared on the top, so we don’t really want to re-declare it, but to extract its content into two new variables.
Thus, we move the const keyword to the beginning, and we get the following:
const [bestFriend, archEnemy] = people
Which translates into: I want to create two variables, bestFriend and archEnemy, out of the people array. The first variable, bestFriend, will capture the value inside the index 0 of people; and the second variable, archEnemy, will capture the value inside the index of 1.
If you’re wondering how the language knows that we mean index 0 and 1, it’s because of the position they hold in the array syntax on the left part of the assignment.
// index 0 index 1
const [bestFriend, archEnemy] = people
Ok so destructuring when working with arrays is nice, but it’s not the common case scenario. Most of the time (or at least that’s been my experience) I find myself using destructuring when working with objects.
Let’s create a person object we can work on as our example.
const bestFriend = {
name: 'Karen',
age: 35,
species: 'Reptilian',
alignment: 'Chaotic neutral',
favorites: [
{ type: 'food', value: 'ice cream' },
{ type: 'animal', value: 'otter' }
]
}
const archEnemy = {
age: 40,
name: 'Unavailable'
}
In object destructuring, you have the opportunity to easily create a variable for each of the properties that you want to access. So we can get away with the following:
const { age, favorites, name } = bestFriend
console.log(age) // 35
console.log(favorites[0].value) // ice cream
console.log(name) // Karen
If you wanted to give the variable a custom name, instead of the name of the property you can easily do it as follows:
const { age: howOld, name: howToCall } = bestFriend
console.log(howOld) // 35
console.log(howToCall) // Karen
Now, usually when you are working with an object and you want to access one of its properties, you would do so like in the following example.
sendItem(bestFriend, bestFriend.favorites[0].value, bestFriend.age)
sendItem(archEnemy, 'coal', archEnemy.age)
At first glance, without knowing the internal API of the sendItem function, this is not looking very clear. We could use simple variables to clarify our intent. We want to send as many gifts to our friend as they are old, and as many coals to the enemy as they are old.
So, age === number of gifts.
const perfectGift = bestFriend.favorites[0].value
const amountOfGiftsForFriend = bestFriend.age
const amountOfCoalForEnemy = archEnemy.age
sendItem(bestFriend, perfectGift, amountOfGiftsForFriend)
sendItem(archEnemy, 'coal', amountOfCoalForEnemy)
Just by making these simple changes you can already see that the readability of the code improves drastically. Now, let’s work on the same example with destructuring.
const {age: amountOfGiftsForFriend, favorites: [{ value: perfectGift }]} = bestFriend
const {age: amountOfCoalForEnemy} = archEnemy
sendItem(bestFriend, perfectGift, amountOfGiftsForFriend)
sendItem(archEnemy, 'coal', amountOfCoalForEnemy)
Let’s destructure (😄) this example so we can better understand what is happening.
In the first line, we are destructuring several properties out of the bestFriend object. We need to know two pieces of data: perfectGift which should be the value of the first item in the favorites array, and amountOfGiftsForFriend which should be equal to the age.
Since we are looking to rename the age property of our object to amountOfGiftsForFriend to make it more readable, we have to use the syntax that allows us to rename this property into another variable. So first, we destructure the age like so:
const { age: amountOfGiftsForFriend } = bestFriend
console.log(amountOfGiftsForFriend) // 35
Next, we need to destructure the favorites property.
const { favorites } = bestFriend
console.log(favorites)
// [
// { type: 'food', value: 'ice cream' },
// { type: 'animal', value: 'otter' }
// ]
Now, stay with me, favorites is an array right? And on the first part of this article we learned that we can destructure arrays by their index. Remember?
So if we need to access the first object in the array, with index 0, we can do array destructuring nested in the same line.
const { favorites: [firstFavorite] }
console.log(firstFavorite) // { type: 'food', value: 'ice cream' }
Now we just need to tell the destructuring syntax which property of this first object we want, and how we want to rename it.
const { favorites: [{ value: perfectGift }] }
console.log(perfectGift) // ice cream
Here is a codesandbox with the example in case you want to check it out yourself.
As I mentioned at the beginning of the article, this small explanation is only meant to get you past that OMG WHAT IS DIS moment when you first encounter the syntax somewhere in the wild.
I personally think that destructuring can bring a lot of clarity to code, and it’s a fantastic tool to have under your belt as a developer. However, I do recommend you give at least a quick read through the examples provided by MDN to deeply understand the power that this syntax can give you.
As always, thanks for reading and share with me thoughts on Twitter at: @marinamosti.
P.S. All hail the magical avocado! 🥑
P.P.S. ❤️🔥🐶☠️
Marina Mosti is a frontend web developer with over 18 years of experience in the field. She enjoys mentoring other women on JavaScript and her favorite framework, Vue, as well as writing articles and tutorials for the community. In her spare time, she enjoys playing bass, drums and video games.