Destructuring Arrays and Objects in JavaScript
This post is part of the Mastering JavaScript Series.
The destructuring assignment is a very versatile tool. This technique can be used for both objects and arrays. We will take a closer look on both data structures.
Named parameters
We can create named parameters for functions with two or more parameters. This way we don't have to deal with ordering problems, the function API is better exposed and it is easier to track down errors caused by missing parameters.
We can refactor this code:
const hello = (name, country) => `Hi, I'm ${name} from ${country}`;
hello('Brazil', 'TK'); // 'Hi, I'm Brazil from TK'
Into a function that receives only one object with all the necessary parameters and use object destructuring to get all the parameters:
const hello = ({ name, country }) => `Hi, I'm ${name} from ${country}`;
hello({ country: 'Brazil', name: 'TK' }); // 'Hi, I'm TK from Brazil'
You can even set default values!
const hello = ({ name = 'TK', country = 'Brazil' } = {}) =>
`Hi, I'm ${name} from ${country}`;
hello(); // 'Hi, I'm TK from Brazil'
Accessing object attributes
Another way we can use the object destructuring is to access the object fields. This makes the code simpler, creating a copy of the targeted field into a variable/constant.
From this:
const person = { name: 'TK', country: 'Brazil' };
const name = person.name;
const country = person.country;
To this:
const person = { name: 'TK', country: 'Brazil' };
const { name, country } = person;
You can use default values here too. For example:
const person = { name: 'TK', country: 'Brazil' };
const { name, country, age = 23 } = person;
name; // 'TK'
country; // 'Brazil'
age; // 23
The age is not part of the person
but it has a default value when the object is destructured.
Accessing array elements
The destructuring feature also works for the array data structure. But instead using the {}
notation, we use the []
to access elements from the array.
Instead of accessing the array elements by an index:
const person = ['TK', 23];
const name = person[0];
const age = person[1];
We use array destructuring:
const person = ['TK', 23];
const [name, age] = person;
Also, in frontend/react applications, it is very common to destructure the array that is returned from a React Hook. For example the useState
hook. It's a function that returns an array of a state and its setter:
Here, it works the same way. Instead of accessing by an index:
import { useState } from 'react';
const defaultPerson = { name: 'TK', age: 23 };
const state = useState(defaultPerson);
const person = state[0];
const setPerson = state[1];
We destructure the array:
import { useState } from 'react';
const defaultPerson = { name: 'TK', age: 23 };
const [person, setPerson] = useState(defaultPerson);
Just like objects, we can also set a default value for array destructuring:
const person = ['TK', 23];
const [name, age, lastName = 'Kinoshita'] = person;
name; // 'TK'
age; // 23
lastName; // 'Kinoshita'
Swapping values
It is also useful if you need to swap values between two variables.
let name1 = 'TK';
let name2 = 'Kazumi';
name1; // 'TK'
name2; // 'Kazumi'
[name1, name2] = [name2, name1];
name1; // 'Kazumi'
name2; // 'TK'
Ignoring values
We saw how we can use destructuring to get attributes from an object or elements from an array. But what if we want to ignore any attribute or element?
In an object, it's pretty straightforward. We just need to not destructure with the attribute we don't want or need.
const person = { name: 'TK', country: 'Brazil' };
const { name } = person;
We just ignore the country
attribute.
But for arrays, we need to understand that they are linear data structure with sequential access, meaning that the sequence matters.
const person = ['TK', 'Brazil', 23];
const [name, , age] = person;
name; // 'TK';
age; // 23
If we want to ignore the 'Brazil'
value but still want the age
element, we can skip it by using an empty space between commas.
Assigning rest
But what if we don't want to ignore it. We care about one of the values and also want to keep an eye on the other ones. In this next example we care about the name
attribute and we want to keep an eye on the rest of the other attributes:
const person = { name: 'TK', country: 'Brazil', age: 23 };
const { name, ...rest } = person;
name; // 'TK'
rest; // { country: 'Brazil', age: 23 }
You can see the rest
still holds all the other attributes that were not destructured.
This ...
is called Spread operator
and the ...rest
is commonly called Rest parameters
.