Destructuring is a new ES6 technique for extracting data from JavaScript objects and arrays using a much tighter, terser, and clearer syntax than that provided by ES5. The result is not just the saving of a few bytes of code; destructuring can change the way you code in radically new ways, and the more you use it, the more ways you’ll find of shaping your data and functions in ways that were simply impossible before. This article goes deep into destructuring, providing you with all you need to know about this magical new syntax.

What is Destructuring?

Destructuring is the opposite of data construction. Rather than constructing a new object or array, for example, destructuring takes data from an existing object or array and literally destructs it to extract only the values you’re interested in.

It does this through the use of a pattern that’s used by ES6 to match the values that you want to extract. This pattern mirrors the structure of the data item you’re destrucuturing, with only those parts of the data item that match the pattern, being extracted.

The data item being destructured lies on the right-hand side of an assignment, and can be any combination of objects and arrays, nested arbitrarily deep. The number of variables you use to assign this data to is not limited.

This article presents a deep dive into everything you need to know about destructuring. To get a better feel for how destructuring works, take a look at the code in runnable form in the accompanying Array Destructuring and Object Destructuring fiddles.

Destructuring Arrays

Array destructuring uses an array as a data item, from which you extract values and assign them to one or more variables according to an array pattern, which is used to match the values you need from the array.

This array pattern uses the position of a value to identify the values you want to extract. It must exactly mirror the structure of the array being destructured, with each variable in the array pattern being assigned the value that corresponds to the same position in the array being destructured.

Some examples will help clarify things.

Example Array Patterns

Assign all items in an array to individual variables

// Setup our array const avengers = ['Tony Stark', 'Steve Rogers', 'Natasha Romanoff']; // Destructure array into individual variables. The array pattern // is on the left of the assignment (i.e. the '=') and the array being // destructured on the right. const [ironMan, cap, blackWidow] = avengers; // ironMan = 'Tony Stark' // cap = 'Steve Rogers' // blackWidow = 'Natasha Romanoff' // Output ironMan: ironMan;

Extract all but the first item

const avengers = ['Tony Stark', 'Steve Rogers', 'Natasha Romanoff']; // We don't need you, Tony const [, cap, blackWidow] = avengers; // ironMan = Error: undefined // cap = 'Steve Rogers' // blackWidow = 'Natasha Romanoff' // Output cap: cap;

Extract all but the second item

const avengers = ['Tony Stark', 'Steve Rogers', 'Natasha Romanoff']; // Missing cap const [ironMan, , blackWidow] = avengers; // ironMan = 'Tony Stark' // cap = Error: undefined // blackWidow = 'Natasha Romanoff' // Output blackWidow: blackWidow;

Extract all but the last item

const avengers = ['Tony Stark', 'Steve Rogers', 'Natasha Romanoff']; // ironMan vs cap const [ironMan, cap] = avengers; // ironMan = 'Tony Stark' // cap = 'Steve Rogers' // blackWidow = Error: undefined // Output blackWidow: ironMan;

Nested Arrays

This concept of pattern matching also works with nested arrays – just ensure the array pattern on the left of the assignment matches the array structure on the right, and again, each variable declared in the array pattern is assigned the value corresponding to its equivalent position in the destructured array. You can nest arrays arbitrarily deep and still destructure from them.

Destructure a nested array

// Destructuring Nested Arrays const avengers = [ 'Natasha Romanoff', ['Tony Stark', 'James Rhodes'], ['Steve Rogers', 'Sam Wilson'] ]; // Avengers and their partners const [blackWidow, [ironMan, warMachine], [cap, falcon]] = avengers; // blackWidow = 'Natasha Romanoff' // ironMan = 'Tony Stark' // warMachine = 'James Rhodes' // cap = 'Steve Rogers' // falcon = 'Sam Wilson' // Output warMachine: warMachine;

Pluck a single value from a deeply nested array

// Plucking Pepper Potts from a deeply nested Array const avengers = [ 'Natasha Romanoff', [['Tony Stark', 'Pepper Potts'], 'James Rhodes'], ['Steve Rogers', 'Sam Wilson'] ]; // Destructure const [ , // Skip over 'Natasha Romanoff' [[ , // Skip over 'Tony Stark' hera // Pepper Potts, assigned to a variable called 'hera' ]]] = avengers; // Note: you can also write this like so: // const [, [[, hera ]]] = avengers; // Output hera: hera; // hera = 'Pepper Potts'

Capture all remaining items with …rest

If you want to capture specific array items, but dump the remaining items in their own array, you can do so by destructuring with the rest operator (…), like so:

// Destructuring with the ...rest operator const avengers = ['Natasha Romanoff', 'Tony Stark', 'Steve Rogers']; const [blackWidow, ...theOthers] = avengers; theOthers; // blackWidow = 'Natasha Romanoff' // theOthers = ['Tony Stark', 'Steve Rogers'] // Output theOthers: theOthers;

Destructuring Objects

Destructuring objects is even more awesome, particularly if you have a complex, deeply nested object whose property values you want to extract. Again, the same rules apply as with arrays – just create an object pattern on the left-hand side of your assignment with the position of the variables you wish to assign to matching the position of values you wish to extract from the object.

With object destructuring, you need to provide the property name whose value you wish to extract, and the name of the variable you want to store the property value in. As with arrays, we need to create an object pattern on the left side of our destructuring assignment that mirrors the object being destructured.

In this case, though, the value that we’re trying to extract is an object property’s value (i.e. we want value in { prop: value } ). Accordingly, our object pattern must have a variable in exactly the same position as the property value we’re trying to extract.

Simple Examples

Extract a single object property value

To assign the value 'Tony Stark' to a variable called a from the property ironMan in the object { ironMan: 'Tony Stark' } , we’d do the following:

// Destructure object's property value to an individual variable called 'a' const { ironMan: a } = { ironMan: 'Tony Stark' }; // Output a: a; // a = 'Tony Stark '

Extract multiple property values

To extract multiple property values from an object, we just extend the same pattern:

// Setup our object const avengers = { ironMan: 'Tony Stark', cap: 'Steve Rogers', blackWidow: 'Natasha Romanoff' }; // Destructure object to individual variables const { ironMan: a, cap: b, blackWidow: c } = avengers; // a = 'Tony Stark ' // b = 'Steve Rogers' // c ='Natasha Romanoff' // Output a: a;

Notice how the destructuring pattern matches exactly the object that we’re destructuring.

Nested Object destructuring

Like nested arrays, we can destructure nested objects of arbitrary depth.

// Setup our object const avengers = { blackWidow: 'Natasha Romanoff', ironManCharacters: { couple: { ironMan: 'Tony Stark', hera: 'Pepper Potts', }, partner: { warMachine: 'James Brodie' } }, capCharacters: { cap: 'Steve Rogers', partner: { falcon: 'Sam Wilson' } } }; // Destructure object to individual variables const { blackWidow: a, ironManCharacters: { couple: { ironMan: b, hera: c }, partner: { warMachine: d } }, capCharacters: { cap: e, partner: { falcon: f } } } = avengers; // a = 'Natasha Romanoff' // b = 'Tony Stark ' // c = 'Pepper Potts' // d = 'James Brodie' // e = 'Steve Rogers' // f = 'Sam Wilson' // Output a: a;

Naming our extracted variables

Of course, naming our variables a , b , c , etc. is horrible, so let’s name them something more meaningful.

Verbose naming

// Setup our object const avengers = { ironMan: 'Tony Stark', cap: 'Steve Rogers', blackWidow: 'Natasha Romanoff' }; // Destructure object to individual variables with meaningful names const { ironMan: ironMan, cap: cap, blackWidow: blackWidow } = avengers; // blackWidow = 'Natasha Romanoff' // ironMan = 'Tony Stark ' // cap = 'Steve Rogers' // Output blackWidow: blackWidow;

Better – but we can do better still. { ironMan: ironMan } seems somewhat ugly and not exactly DRY.

Syntactical naming shortcuts

If you want to assign the value of an object property to a variable of the same name as the property’s, you can simply list the property name once in the destructuring pattern, like so:

// Setup our object const avenger = { ironMan: 'Tony Stark' }; // Destructure object to individual variables with meaningful names const { ironMan // equivalent to 'ironMan: ironMan' } = avenger; // ironMan = 'Tony Stark ' // Output ironMan: ironMan;

Because both destructured property name and the name of the variable we’re assigning it to are the same, we only need to list the name once.

Final terse syntax

By reformatting our code slightly, we can make it look terser and cleaner:

// Setup our object const avengers = { ironMan: 'Tony Stark', cap: 'Steve Rogers', blackWidow: 'Natasha Romanoff' }; // Destructure object to individual variables with meaningful names const { ironMan, cap, blackWidow } = avengers; // Output ironMan: ironMan;

Extracting a deeply nested property form an object

Things get even more interesting when we want to extract the value of a deeply nested property:

// Setup our object const avengers = { blackWidow: 'Natasha Romanoff', ironManCharacters: { couple: { ironMan: 'Tony Stark', hera: 'Pepper Potts', }, partner: { warMachine: 'James Brodie' } }, capCharacters: { cap: 'Steve Rogers', partner: { falcon: 'Sam Wilson' } } }; // Destructure a deeply nested object const { ironManCharacters: { couple } } = avengers; // couple = { // ironMan: 'Tony Stark', // hera: 'Pepper Potts', // } // Output couple: couple;

Wait, WTF?! How do you read this? And how in the world is couple the variable being defined here?

By breaking this down, we see that the left side of our assignment is mirroring part of the object we’re destructuring:

const avengers = { ironManCharacters: { couple: { ironMan: 'Tony Stark', hera: 'Pepper Potts', } } }; const { ironManCharacters: { couple } } = avengers; // Output couple: couple;

Just using const { couple } = avengers; isn’t enough to extract the value of couple – you have to mirror the position of the property you want to extract as well as the property name. By doing this, you give the JavaScript compiler the information it needs to walk down the object’s properties and extract exactly the value you’re interested in.

Also notice that couple is using the syntactical shorthand for variable naming, so it’s actually:

const { ironManCharacters: { couple: couple } } = avengers;

So that’s how couple is the variable that’s being defined, and its value is that of the object property named couple in the avengers object.

Destructure to object properties

So far we’ve destructured an object’s values to individual variables, but we can also destructure to another object’s properties:

const avengers = { blackWidow: 'Natasha Romanoff', ironManCharacters: { couple: { ironMan: 'Tony Stark', hera: 'Pepper Potts' } } }; const ironManProperties = { family: {} }; ({ ironManCharacters: { couple: ironManProperties.family } } = avengers); ironManProperties.family // ironManProperties.family = { // ironMan: 'Tony Stark', // hera: 'Pepper Potts' // } // Output ironManProperties.family: ironManProperties.family;

What we’re doing here is assigning the ironManCharacters.couple property to the ironManProperties.family property. There are two things to note here:

The destructuring assignment is wrapped in parentheses

We have to do this as we’re destructuring to an existing variable ( ironManProperties in this case), rather than declaring a new variable (see below). We’re still pattern matching

{ ironManCharacters: { couple... } } matches the ironManCharacters pattern of the avengers object. This extracts the value of ironManCharacters.couple from the avengers object, as you’d expect. But now, as the new object ironManProperties and its property family is placed next to couple , it’s the object property ironManProperties.family that is assigned this value.

Confusing? Only when you try to explain it! Play around with it in this fiddle, and it’ll soon make sense.

If you’re wondering why you’d ever want to do something like this, take a look at the examples in the next post, where you’ll see how just such a pattern is used to destructure a JSON object from an API call. Then you’ll see how powerful destructuring can be.

Default Values

You can give a variable a default value during destructuring:

// Setup our object const avengers = { ironMan: 'Tony Stark', cap: 'Steve Rogers', blackWidow: 'Natasha Romanoff' }; // Destructure using defaults const { ironMan, cap, blackWidow, theHulk='Bruce Banner' } = avengers; // ironMan = 'Tony Stark' // cap = 'Steve Rogers' // blackWidow = 'Natasha Romanoff' // theHulk = 'Bruce Banner' // Output blackWidow: blackWidow;

Things you can’t do with destructuring

Destructuring assignment without const, let or var

We already touched on this when discussing destructuring to an object property, but it’s worth noting again for clarity:

You can’t directly destructure to a variable that’s already been declared.

That is, you can only destructure to a variable that’s being declared at the same time (i.e. with a const , let , or var ).

// Setup our object const avengers = { ironMan: 'Tony Stark', cap: 'Steve Rogers', blackWidow: 'Natasha Romanoff', theHulk: 'Bruce Banner' }; // Valid destructuring const { ironMan } = avengers; let { cap } = avengers; var { blackWidow } = avengers; // Invalid destructuring let theHulk; { theHulk } = avengers; // Error // Output theHulk: theHulk;

Why can you not destructure to a variable that’s already been declared? Because you cannot start a statement with a curly bracket ( { ), as JavaScript thinks you’re declaring a block.

The solution is to wrap the whole destructuring assignment up in parentheses

How to destructure to an already-declared variable

// Setup our object const avengers = { ironMan: 'Tony Stark', cap: 'Steve Rogers', blackWidow: 'Natasha Romanoff', theHulk: 'Bruce Banner' }; // A valid Hulk let theHulk; ({ theHulk } = avengers); // theHulk = 'Bruce Banner' // Output theHulk: theHulk;

Now we’re not starting the line with a curly bracket, so JavaScript doesn’t think we’re declaring a block, and so will start destructuring like we want it to.

Directly return a destructured assignment

You cannot directly return a value from a destructured assignment without first creating a variable that you then subsequently return. For example, the following will return the entire ironMan object, and not the value ‘Tony Stark’ that the function name promises:

// Note: this doesn't work! function getTonyStark(avengers){ return { ironMan: { realName } } = avengers; // return the avengers object, not the realName value } const avengers = { ironMan: { realName: 'Tony Stark' } }; const tonyStark = getTonyStark(avengers); // tonyStark = { // ironMan: { // realName: 'Tony Stark' // } // }; // Output tonyStark: tonyStark;

To extract a value from a destructured object, you must first assign it to a variable, and then return that variable separately:

// Note: this DOES work! function getTonyStark(avengers){ const { ironMan: { realName } } = avengers; return realName; } const avengers = { ironMan: { realName: 'Tony Stark' } }; const tonyStark = getTonyStark(avengers); // tonyStark = 'Tony Stark' // Output tonyStark: tonyStark;

This is annoying, as separating the assignment and return on two lines is ugly and seems unnecessary. Unfortunately, that’s how JavaScript destructuring works – you must first assign the destructured value to a variable and then return it separately.

Summary

That’s quite a deep dive of the key principles of destructuring. Just knowing how things work, though, isn’t enough to show you what you can actually do with this powerful construct.

In the next article, therefore, I’ve put together a list of some advanced destructuring techniques that really show the power of destructuring in ways you may never have thought of.

All posts in this series on destructuring

Fiddles for this article

Destructuring Articles around the Web

If you still want more, check out the following: