
Beginner-Intermediate
A basic grasp of JavaScript is helpful when learning about more advanced techniques.
One very handy feature that JavaScript added was destructuring. You may have heard of it and perhaps even used it. Did you know you can destructure a nested object? Did you know you can probably do a lot more with it than you think? In this post I want to explore the possibilities of this feature and how it can clean up your code.
How Basic Destructuring Works
If you haven’t heard of destructuring, you’ve probably at least seen it somewhere. Let’s go over a basic example. Let’s pretend we got an API response that returns information about numbers.
const results = { numbers: { one: { value: 1, name: "One" }, two: { value: 2, name: "Two" }, three: { value: 3, name: "Three" } } }
If we wanted to access variables one
, two
, and three
, we do so by accessing results
then numbers
. It would look something like this:
const one = results.numbers.one const two = results.numbers.two const three = results.numbers.three console.log(one, two, three) // CONSOLE // [object, object] // [object, object] // [object, object]
To access these three values, we need to drill into results.numbers
then access each of the number objects. Now let’s see how destructuring can clean up some of the repetitiveness.
const { one, two, three } = results.numbers
You probably already notice that this is only one line! We are able to access as many variables off of the results.numbers
object as we’d like. If I wanted to only get two
, it’d be const { two } = results.numbers. The key thing here is how much less repetitive this method is.
What we are basically saying is “I want values one
, two
, and three
off of the results.numbers
object. You likely see this pattern a lot when using npm libraries. If you see something like import { throttle } from 'lodash'
, it is doing the same thing. We are saying “I want the throttle method from lodash”. It’s the same principal here!
What if We Want a Unique Variable Name For Each Grabbed Property?
There may be cases where we don’t want the variable names to be one
, two
and three
. Maybe one should be numberOne
. Destructuring can handle this with similar clean syntax.
const { one: numberOne, two: numberTwo, three :numberThree } = results.numbers console.log(numberOne, numberTwo, numberThree) // CONSOLE // [object, object] // [object, object] // [object, object]
Here, we are saying “grab one
from results.numbers
and name it numberOne
, grab two
from results.numbers
and name it numberTwo
” and so on. If you look at the console.log
, we are accessing these values by those names.
Access Values In Nested Objects
We can modify the current example to grab from the numbers
object within the main results
object. Let’s see how to do this.
const { numbers: { one, two, three } } = results
We moved the numbers
in results.numbers
to be part of the destructured object. Now we are saying “Get the numbers
object from results
and grab one
, two
and three
from numbers
. Whether you want to destructure a nested object like this is all up to you. I prefer not doing it like this because I find the other syntax cleaner, but it will always depend on the use case.
Destructuring Arrays
ES6 also provides a clean way to destructure arrays. Let’s say the API returns numbers as an array instead.
const results = { numbers: [1,2,3,4,5] } const [one, two] = results.numbers console.log(one, two) // CONSOLE // 1 // 2
The variables one
and two
associate with the indexes in the array. Instead of taking properties from an object, we are taking values from specific indexes in the array. Quite handy! What if we want to skip over indexes? ES6 provides a somewhat funky but useful syntax for this.
const results = { numbers: [1,2,3,4,5] } const [one, two,, three] = results.numbers console.log(one, two, three) // 1 // 2 // 4 <- skipped over 3 because of the second comma const [one,, two,, three] = results.numbers console.log(one, two, three) // 1 // 3 <- skipped over 2 because of the second comma after one // 5 <- skipped over 4 because of the second comma after two const [one,,,, two] = results.numbers console.log(one, two) // You can of course use multiple commas to skip to a farther index // 1 // 5 <- 3 extra commas means we skipped over 3 indexes to get to 5
As you can see here, array destructuring allows for a lot of flexibility while keeping the syntax short.
Using The Spread Operator To Destructure Multiple Array Items
What if we expect this array to grow and we want to grab all of the values that aren’t the first two? With the spread operator, this is quite easy:
const results = { numbers: [1,2,3,4,5,6,7,8,9] } const [one, two, ...arr] = results.numbers console.log(one, two, arr) // 1 // 2 // [3,4,5,6,7,8,9]
If you are unfamiliar with the spread operator, all it’s doing is grabbing the remainder of the array items. It’s a good option to have for certain use cases.
Now You Know
I never knew there was a way to destructure nested objects. JavaScript seems to always have little tricks nested up its sleeve. What’s wonderful about discovering new ES6 features is finding ways to implement them in current and future projects! I implore you to do the same.