JS: Destructuring
Anthony Petrides
Posted on July 2, 2021
A deep dive into the powerful world of javascript destructuring
Jump to:
Array Destructuring
Take the arrays called alphabet and numbers below.
const alphabet = ['A', 'B', 'C', 'D', 'E', 'F']
const numbers = [1, 2, 3, 4, 5, 6]
To destructure alphabet, you simply set what you want to destructure equal to the name of the array as follows:
const [a, b, c] = alphabet
Note that we wrap a, b and c in square brackets purely because we are destructuring an array. Had we been destructuring an object, they'd be wrapped in curly braces { }. We'll touch more on this later on.
For now, we have destructured the first 3 elements of the alphabet array, into variables called a, b and c. To prove this, if we run the below:
console.log(a);
console.log(b);
console.log(c);
We would get back in our development console:
A
B
C
What if I want to skip element?
If you wanted to, for example, skip the second element, you could simply leave an empty comma , when destructuring per below:
const [a,, c] = alphabet
Now logging the following:
console.log(a);
console.log(b);
console.log(c);
Would return:
A
C
What if I want the rest of the array?
If you wanted to print the rest of the array while destructuring, because maybe you want to return the array without the first element for example, you can do this by combining the spread operator ...
const alphabet = ['A', 'B', 'C', 'D', 'E', 'F']
const [,b, ...restOfTheElements] = alphabet
So in the above example, we destructure the alphabet on the second line, skipping the first element (as marked by the empty comma ,) then we assign the second element's value to b, and then we use the spread operator (...) to say we want the rest of the elements in the array thereafter. You need to suffix the spread operator (...) with the name you'd like to give the rest of the array. Above we've simply called it 'restOfTheElements'.
Now, What does this look like?
console.log(b);
console.log(restOfTheElements);
Would return:
B
['C', 'D', 'E', 'F']
Combining 2 Arrays
You can also use the spread operator to combine 2 arrays together per the below example:
const combinedArray = [...alphabet, ...numbers]
console.log(combinedArray);
This would return:
['A', 'B', 'C', 'D', 'E', 'F', 1, 2, 3, 4, 5, 6]
Granted this isn't the most useful feature when it comes to arrays, given you could achieve the same with:
const combinedArray = alphabet.concat(numbers)
However, this will come in handy when we touch on combining 2 or more objects together later on.
Destructuring with Functions
Lets take the below example:
function addAndMultiply(a, b) {
return [a+b, a*b];
}
const array = addAndMultiply(4, 2);
console.log(array) //returns [6, 8]
We can apply array destructuring here per below:
function addAndMultiply(a, b) {
return [a+b, a*b];
}
const [sum, multiply] = addAndMultiply(4, 2);
console.log(sum) //returns 6
console.log(multiply) //returns 8
What we're saying here is that we are destructuring the return from addAndMultiply(4, 2) as two different variables - one called sum, and one called multiply. Again, we destructure with [ ] because the return of addAndMultiply(4, 2) is an array, and we destructure into variables 'sum' and 'multiply' in that order, because that is the order that are returned in within the 'addAndMultiply' function.
Destructuring with Default Values
We can also take the previous example and demonstrate destructuring with default values. For example:
function addAndMultiply(a, b) {
return [a+b, a*b];
}
const [sum, multiply, subtract = 'Subtraction Default'] = addAndMultiply(4, 2);
console.log(sum) //returns 6
console.log(multiply) //returns 8
console.log(subtract) // returns 'Subtraction Default'
Object Destructuring
The true power of destructuring in Javascript
Take the two simply objects below, personOne and personTwo:
const personOne = {
name: 'Naruto',
age: 29,
address: {
city: 'Tokyo'
country: 'Japan'
}
}
const personTwo = {
name: 'Sasuke',
age: 28,
address: {
city: 'Osaka'
country: 'Japan'
}
}
If we want to get the name and age of personOne, we can use destructuring as follows:
const { name, age } = personOne
console.log(name); //returns 'Naruto'
console.log(age); //returns 29
Note that we wrap name and age in curly braces { } because we are destructuring an object.
And unlike array destructuring, which grabs elements in the array in sequential order, object destructuring matches by the key. I.e. name had to match name in the personOne object.
You can however rename the variable that you're destructuring if you so desire.
For example, we can destructure name from the object, but call it firstName instead as follows:
const { name: firstName, age } = personOne
console.log(firstName); //returns 'Naruto'
console.log(name); //returns nothing as we remapped the var
Defaults
We can also still use defaults in object destructuring. Lets take personTwo for example:
const personTwo = {
name: 'Sasuke',
age: 28,
address: {
city: 'Osaka'
country: 'Japan'
}
}
const { name: firstName, age, job = 'Shinobi' } = personTwo
console.log(firstName); //returns 'Sasuke'
console.log(age); //returns 28
console.log(job); //returns 'Shinobi'
Above we can see we've added a property called job to the destructuring, and although it doesn't exist in the personTwo object, it has a default value set so it does return the value.
Similarly, if we added job to the object, it's default value would be overridden as follows:
const personTwo = {
name: 'Sasuke',
age: 28,
job: 'ninja',
address: {
city: 'Osaka'
country: 'Japan'
}
}
const { name: firstName, age, job = 'Shinobi' } = personTwo
console.log(firstName); //returns 'Sasuke'
console.log(age); //returns 28
console.log(job); //returns 'ninja'
You can even add defaults to renamed object variables too, per the below example:
const personTwo = {
name: 'Sasuke',
age: 28,
job: 'ninja',
address: {
city: 'Osaka'
country: 'Japan'
}
}
const { name: firstName = 'Tony', age, job = 'Shinobi' } = personTwo
console.log(firstName); //returns 'Sasuke'
As you can see above, we have name remapped to firstName, and have then also given it a default value of 'Tony'. Meaning if the name property did not exist within the personTwo object, then console.log(firstName) would return the default 'Tony'.
Spreading
We can also use the spread operator here (just like we did with array destructuring) in order to get back the rest of the object. For example:
const personTwo = {
name: 'Sasuke',
age: 28,
job: 'ninja',
address: {
city: 'Osaka'
country: 'Japan'
}
}
const { name: firstName = 'Tony', age, ...rest } = personTwo
console.log(firstName); //returns 'Sasuke'
console.log(age); //returns 28
console.log(rest);
//returns { job: "ninja", address: {city: "Osaka", country: "Japan"}}
As you can see, we've spread the rest of the object after destructuring the age, and we've mapped it to a variable called 'rest'. So when we log 'rest', we get the remainder of the object.
Destructuring Nested Objects
We can also destructure nested objects.
Let's say we want to get only the city from personTwo. We can do this as follows:
const personTwo = {
name: 'Sasuke',
age: 28,
job: 'ninja',
address: {
city: 'Osaka'
country: 'Japan'
}
}
const { name: firstName = 'Tony', address: { city } } = personTwo
console.log(city); //returns 'Osaka'
Combining Objects
We can also use destructuring to combine objects.
Below, we will create a personThree using parts of personOne and personTwo.
Note that personTwo has been shortened to just age and job for the purposes of this example.
const personOne = {
name: 'Naruto',
age: 29,
address: {
city: 'Tokyo'
country: 'Japan'
}
}
const personTwo = {
age: 28,
job: 'ninja',
}
const personThree = {...personOne, ...personTwo}
- Take everything inside personOne ---> put it in an object called personThree
- Take everything inside personTwo --> also put it in the same personThree object, but overwrite anything that was already in personOne.
What does this give you?
console.log(personThree);
//returns
const personThree = {
name: 'Naruto',
age: 28,
job: 'ninja',
address: {
city: 'Tokyo'
country: 'Japan'
}
}
As you can see, the result of personThree is a spread personOne, overridden with anything that was in personTwo when it was spread into the same object thereafter.
Object Destructuring Inside Function Arguments
Object destructuring inside of function arguments can be a powerful tool when it comes to code simplicity.
Take the below example which demonstrates passing personOne into a printPerson function, and printing some text that grabs particular attributes from the object, such as name and age in this example:
const personOne = {
name: 'Naruto',
age: 29,
address: {
city: 'Tokyo'
country: 'Japan'
}
}
const printPerson = (person) => {
console.log('Name: ${person.name}. Age: ${person.age}.);
}
printPerson(personOne);
//returns
"Name: Naruto. Age: 29"
If we used object destructuring within the function argument, we could avoid having to repeatedly prefix the attributes we want to pluck out with person.
Using object destructuring, we can rewrite the function as follows:
const printPerson = ({ name, age }) => {
console.log('Name: ${name}. Age: ${age}.);
}
printPerson(personOne);
//returns
"Name: Naruto. Age: 29"
As you can see, the above returns the exact same output.
What's happening exactly?
Well, as you can see we're passing in personOne to printPerson when we call the function. And in the argument of the printPerson function we're destructuring personOne saying all we want is the name and the age.
We can also add defaults to the destructured arguments as follows:
const personOne = {
name: 'Naruto',
age: 29,
address: {
city: 'Tokyo'
country: 'Japan'
}
}
const printPerson = ({ name, age, favouriteFood = 'Ramen'}) => {
console.log('Name: ${name}. Age: ${age}. Favourite Food: ${favouriteFood}.);
}
printPerson(personOne);
//returns
"Name: Naruto. Age: 29. Favourite Food: Ramen."
Above you can see we've added a default for favouriteFood which currently does not exist in personOne so is being used. But if we added it to personOne then it would not use the default we've specified per below:
const personOne = {
name: 'Naruto',
age: 29,
favouriteFood: 'Takoyaki'
address: {
city: 'Tokyo'
country: 'Japan'
}
}
const printPerson = ({ name, age, favouriteFood = 'Ramen'}) => {
console.log('Name: ${name}. Age: ${age}. Favourite Food: ${favouriteFood}.);
}
printPerson(personOne);
//returns
"Name: Naruto. Age: 29. Favourite Food: Takoyaki."
This is arguable the single most useful section of object destructuring - specifically when using it in React projects where you'll find object destructuring is heavily used in function calls.
Thanks for sticking through to the end! :)
Posted on July 2, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.