![Destructuring in JavaScript](https://soshace.com/wp-content/uploads/2019/12/destructuring-in-javascript.jpg)
We make use of objects and array to hold collective data – you can have an array of books, or shoes, an object which holds the information of a user. These data need to be accessed in the places where we need to make use of them, mostly to show the information to the user. Using an object, for example, let’s say we have the details of a customer pulled from the backend of our application and it looks like this.
current_customer = { name: "Jane Doe", email: "[email protected]", location: "Lagos, Nigeria", gender: "female", last_purchase: "Solace Bracelet" }
To access the email address, we have to do current_customer.email, that’s quite straight forward. What if we have an array of the customer’s purchases in the object like so;
current_customer = { name: "Jane Doe", email: "[email protected]", location: "Lagos, Nigeria", gender: "female", last_purchase: "Solace Bracelet", purchases: [ { item: "Strapped Heeled Sandals", quantity: "2", amount: "$70" }, { item: "Snake Sandals", quantity: "1", amount: "$30" } ] }
To display the name first item the user purchase, we have to do something like customer.purchases[0].item. This can grow in complexity depending on the structure of the data. What if there was a simple and neat way to do this. I mean, something like this;
const { purchases: [ { item } ] } = current_customer console.log(item) // "Strapped Heeled Sandals"
Wow, isn’t that cleaner? That’s no magic, let’s step back a little, and a little more.
What is Destructuring?
Let’s assume that the creating of objects and arrays is called construction, destructuring will be the opposite of that – which is the extracting of values from objects or array and assigning them to certain values. Most times, the values being extracted are not all the values in the object or array, but the ones you want to make use of. Like you can see in the example above, we only extracted the value stored in the item variable and we were able to access it using its key. It is important to note that destructuring is not the destruction of the array or object – the values stores in the array or object will still be available. Destructuring only makes it easy to access these values by storing them in the variables.
Taking a cue from the example we have above, it’s like we directly assigned the value to the variable. In this tutorial, we will see how to destructure arrays and objects.
Array Destructuring
When destructuring an array, you need to note the position of the values in the array you want to destructure. This is how the values you want to extract from the array will be identified. Let’s make use of a basic array like this – const details = [“Jane Doe”, “[email protected]”, “Female”, “20”, “Lagos, Nigeria”, “+2348011223344”].
Here is how a simple destructuring of the array will look like;
const [name, email, gender, age, location, phone_number] = details
Logging any of the variables above will give us the value at that exact position when the array was created. You can see that it looks like we are creating an array, the difference is that the array literal is on the left-hand side of the assignment – we are setting up variables to hold the data contained on the right-hand side of the assignment, the value a variable will hold will depend on its position and that of the value in the array. It means that to extract the first and second values, we only need two variables, like so.
const [name, email] = details
This will contain the values, Jane Doe and [email protected] respectively.
Skipping Values
What happens when we want the first, second, and last values. This implies that we want to skip the values we do not need. That’s very possible, we’ll have to make use of a comma in the place of the values we want to skip – instead of having a variable in that place, we’ll use a comma.
const [name, email, , , , phone] = details
It is important to take note of the number of commas we have. In this case, we’ll need four commas – the last 3 commas are used in place of the items that are meant to be there – the items we are skipping. This means that we are skipping four items. There are no rules on the number of items that can be skipped, other than using commas in place of the item(s) to be skipped. This might be tricky, here’s a good hack you can make use of if you know the length of the array, the number of commas you should have must be equal to the number of items you want to skip plus one.
Using Rest Operator
There might be a situation where you want to collate a certain number of items in an array while you extract others. These have to be placed together, and also towards the end of the array. A typical example will be to extract the name and email values and have the others in an array. We can do that using destructuring and the ES6 Rest Operator.
const [name, email, ...rest] = details
After setting the variable for name and email, we capture (store) the remaining values in the variable called rest. This is possible because we prefixed the variable with …. That means we can use a name different from rest. The rest operator by default makes it possible to capture an infinite number of values in an array. In our case, we are capturing the remaining values not stored in a variable in a new array.
Default Values
From what we have covered so far, you can see that the variable maps to the value that matches its position. In cases where there are no variables for the position of a value, the value does not get extracted. Going further, this means that we can pass variables that are less than the number of values in an array if that is the case, can we pass values that are more than the number of values in an array. Think about it for a moment. If you cannot come up with an answer let’s see that in practice. In this case, we’ll create a new array.
const web_details = ["Soshace", "https://soshace.com"]
If we do this
const [name, web_address, blog_address] = web_details
What will be the value of blog_address? It will be undefined. Technically, we declared the variable blog_address and like all declared variables in JavaScript, its value will be undefined. It does not have a value because there is no value in the array that maps to its position. We can take it a notch further and assign a default value to it.
const [name, web_address, blog_address = "https://soshace.com"] = web_details
If there was a value in that position, the value will override the default value we passed.
Nested Arrays
Arrays can get complicated, it is possible to come across nested arrays, these too can be destructured. The major difference between this and the examples above is the structure. Here is an example;
const web_details = ["Soshace", "https://soshace.com", ["Kingsley Silas", "JavaScript"]]
To destructure the outer and inner array we will have
const [title, web_address, [author_name, language]] = web_details
The structure is the only thing that changes as the array becomes deeply nested,
// Array Example const web_details = ["Soshace", "https://soshace.com", ["Kingsley Silas", ["JavaScript", "React"]]] // Destrucuting const [title, web_address, [author_name, [language, framework]]] = web_details
As we did in the examples above, we can also skip values, assign default values, and capture values using the rest operator.
Object Destructuring
The main difference between array and object destructing is the change in literal – in object destructuring, you make use of the object literal, which is the curly braces. This literal has to be on the left-hand side of the assignment operator. Let’s bring back the first code snippet we saw when we embarked on this journey,
current_customer = { name: "Jane Doe", email: "[email protected]", location: "Lagos, Nigeria", gender: "female", last_purchase: "Solace Bracelet" }
When creating an object, we make use of key-value pairs, this technique comes in handy when destructuring – unlike in the case of an array, you do not need to always remember the position of the value (or pair) you want to destructure. As long as you are making use of the key to extract the value, the key will map to its assigned value in the object.
const { email, name, gender } = current_customer
These variables will have the values they were paired with when the object was created. This makes object destructuring more fun to work with. We can take it a step further by assigning a new variable to the value like so.
const { email, name: full_name, gender } = current_customer
Now we can get the name of the user using a new variable full_name. Since we do not have to remember the positions of the values, it makes it easy to skip items – there is no need using commas to skip values – the item will be skipped if its key is not included in the object literal. The reason we need commas in the case of an array is that array destructuring makes use of the position of the values.
Default Values
As we learned when destructuring an array, it is also possible to set default values. This works like that of array destructuring – when you include a key that does not map to any value, the value of the key will be undefined. Instead of having it as undefined, you can go ahead to set it to a value.
const { name, email, phone = "+2348122334455" } = current_customer
Even though the phone variable was not created initially, we now have a value for it that we can go on to make use of.
Rest Operator
If you’re wondering if we can also make use of the rest operator like we did in the case of an array destructuring, I have good news for you, yes we can! The rest operator will collect the rest remaining data (the key and value pair) in an object.
const { name, ...data } = current_customer
We can now access the remaining data using data. You are not restricted to what the variable can be, you only have to prefix it with ….
Nested Objects
If we include a new object inside the current_customer object, we’ll be able to extract the values contained in it.
current_customer = { name: "Jane Doe", email: "[email protected]", location: "Lagos, Nigeria", gender: "female", last_purchase: { item_name: "Solace Bracelet", quantity: 3 } }
Like we did in the case of destructuring a nested array, we have to embed an object literal inside the first one, and then include the key of the value we want to destructure.
const { name, email, last_purchases: { item_name, quantity } } = current_customer
When destructuring the inner object, we had to specifically add the key of the object, without that we will not be able to extract the values contained in it. Doing this will not work.
const { name, email, { item_name } } = customer
Even if the object grows in complexity – if the objects are deeply nested, the same rules apply.
Destructuring Objects and Array
In an earlier example, you saw the destructuring of an object that contained an array.
current_customer = { name: "Jane Doe", email: "[email protected]", location: "Lagos, Nigeria", gender: "female", last_purchase: "Solace Bracelet", purchases: [ { item: "Strapped Heeled Sandals", quantity: "2", amount: "$70" }, { item: "Snake Sandals", quantity: "1", amount: "$30" } ] }
When destructuring this kind of data, you need to be conscious of what you want to extract and where it fits. In the above code snippet, the value of purchases is an array. While you can make use of the key purchases to destructure its value, you’ll need to make use of the position of the objects in the array in order to destructure them, like so.
const { name, purchases: [ first, second ] } = current_customer
first and second will map to the value (objects) in that position. To extract the item’s name and amount, we’ll make use of object literal inside the array literal.
const { name, purchases: [ { item: first_item, amount: first_amount }, { item: second_item, amount: second_amount } ] } = current_customer
If you can always remember the differences between array and object destructuring, it will be easy to work with mixed destructuring.
Destructuring in Function Parameters
Objects or arrays can be passed as parameters to functions. You might not always use all the data contained in this object or array, in such case, you can make use of destructuring to extract the values you want to use. Let’s say we have a function that is used to calculate the total amount of customer has paid for everything the purchased from our store. Without destructuring, here is how the function will look like.
const calculateTotalAmount = (current_customer) => { let totalAmount = 0; current_customer.purchases.map(item => { let amount = item.quantity * item.amount; totalAmount += amount; }); return totalAmount; }
Here we are passing in the complete current_customer object, though we only need to make use of purchases. We can rewrite the function to look like this.
const handleTotalAmount = ({ purchases }) => { let totalAmount = 0; purchases.map(item => { let { quantity, amount } = item let newAmount = quantity * amount; totalAmount += newAmount; }); return totalAmount; }
You can see that we also used destructuring in the function, awesome right?
Conclusion
Destructuring is a handy tool to make use of as you write your code, it helps reduce the complexity of your code, making it more readable and human-friendly. Even if you prefer not to use it, understanding it cannot be overestimated due to its popularity.
In this tutorial, we have seen how to destructure objects and arrays. The main differences between both are;
- You make use of object literal when destructuring objects, and array literal when destructuring arrays.
- For arrays, you make use of the value’s position and for objects, you make use of the value’s key.
Good one. Informative and clear