Object and array destructuring in JavaScript

30 Mar 2020
javascript

When ES2015 (also known as ES6) got released, powerful new features saw the day like the destructuring assignment syntax. In short, it allows us to unpack values from arrays or properties from objects quickly and straightforwardly.

Consider this post as a quick reference when you want to check out something on destructuring in JavaScript. ☺️

Let’s say you have a user object with different properties like the name, the age, the email address. You want to assign variables to these different properties, here is how to do it with and without destructuring:

// The old way: a bit verbose
const name = user.name
const age = user.age
const email = user.email
// Using destructuring
const { name, age, email } = user

Short and clear: that’s the power of destructuring.

Now, let’s say your user also has an address property, itself composed of a street, city, country, and postal_code properties. You can also use destructuring to handle nested objects:

// Assign the name, email, city and country
const {
name,
email,
address: { city, country },
} = user

But what if you would like to assign the city and country variables while keeping the whole address object? That’s still possible:

// Destructure city, country and keep the address object as-is
const {
address,
address: { city, country },
} = user

Sometimes when you retrieve data from an API, the variable names can be quite different. Let’s imagine that the user object has an user_id property, and you want to rename it just id. It’s useful in these cases to rename variables while destructuring using:

// Destructure user_id and rename it to id
const { user_id: id } = user

The power of destructuring doesn’t stop here. You can assign default values to properties in case they’re not defined. For example, if your user were to have a favorite theme (light or dark) property, you could default it to light mode:

// If `theme` isn't defined, use the light mode by default
const { name, theme = "light" } = user

Note that everything said above also works for function arguments. For example, you could imagine a displayAddress function taking a user object argument:

// Destructure the user object and set the country to France by default
function displayAddress({ name, address: { city, country = "France" } }) {
// Note the use of template literals, another ES2015 feature
return `${name} lives in ${city}, ${country}`
}

If you’re using React, it can also be useful when creating functional components:

const User = ({ name, age, email }) => (
<div>
<p>
{name}, {age} years old
</p>
<p>{email}</p>
</div>
)

Note that it’s also possible to destructure some properties of an object and still save the rest of the properties using the rest parameter:

// Assign the name and the email of the user and store the other properties in userInfos
const { name, email, ...userInfos } = user

It can also be handy in React if you need some props and need to pass down the other props. Here’s an example applied to routing in React:

const PrivateRoute: React.FC<Props> = ({ component: Component, ...rest }) => {
// Get the user's authentication status
const { isAuthenticated } = useAuth()
return (
<Route
// Pass all the props to Route except `component`
{...rest}
render={(props) =>
// if the user is authenticated, render the component otherwise redirect him to the signin screen
isAuthenticated ? <Component {...props} /> : <Redirect to="/signin" />
}
/>
)
}
// Can be used that way:
// <PrivateRoute path="/create" component={CreatePost} />

Wait, wait, wait. The next one is even cooler. You can make use of dynamic destructuring by using computed property keys. Let’s imagine that you have a users object and you want to normalize it by user ID (meaning that the key is the user ID). You can do that with destructuring:

const users = [
{ id: "afb4d", name: "Mike", age: 27 },
{ id: "fea4i", name: "Emma", age: 38 },
]
const normalizedUsers = users.reduce((usersById, user) => {
return {
// Assign the user object to its ID...
[user.id]: user,
// ... and return the whole normalized users object
...usersById,
}
}, {})
/*
normalizedUsers is now
{
afb4d: { id: 'afb4d', name: 'Mike', age: 27 },
fea4i: { id: 'fea4i', name: 'Emma', age: 38 }
}
*/

Destructuring also works for arrays. Let’s say you retrieve a list of users (let’s call it mostActiveUsers) sorted by the number of comments a user posted. You only want to display the first three users:

// Retrieve the first three most active users
const [first, second, third] = mostActiveUsers

What if you’d like to get only the fourth user from this list? Well, it’s also possible to skip items:

// Skip the first three most active users
const [, , , fourth] = mostActiveUsers

You could also get the first three most active users and still store the other users with the rest parameter:

const [first, second, third, ...otherUsers] = mostActiveUsers

Let’s recap. You saw how to destructure objects (with nested objects), rename variables, assign default values, how destructuring applies to function arguments (and thus to components in React), dynamic destructuring, destructuring arrays, skipping array items and also how to use the rest parameter with both objects and arrays. You’re now ready to unlock the full potential of destructuring in your app! 😎

👀This post may also interest you

What you should know about JavaScript arrays


Join the newsletter and read an exclusive post!

No spams. Unsubscribe at any time.

Powered by Buttondown.

© 2020 Thomas Lombart