In JavaScript, the destructuring assignment allows you to extract individual items from arrays or objects and place them into variables using a shorthand syntax.
When working with complex data, destructuring can simplify your code by allowing you to easily extract only the values that you need, assign default values, ignore values, and use the rest property to handle the leftover elements or properties.
It is often used in scenarios such as working with APIs responses, functional programming, and in React and other frameworks and libraries.
By simple example, destructuring can make your code look cleaner and easier to read:
// From this:
const author = article.author;
const title = article.title;
const topic = article.topic;
// To this:
const { author, title, topic } = article;
How to use the Destructuring Assignment
Destructuring Arrays
Presume we have an array:
const myArray = ['a', 'b', 'c'];
Destructuring permits a simpler and less error-prone alternative to extracting each element:
const [one, two, three] = myArray;
// one = 'a', two = 'b', three = 'c'
You can ignore certain values by leaving omitting a value name when assigning, e.g.
const [one, , three] = myArray;
// one = 'a', three = 'c'
or use the rest operator (...
) to extract remaining elements:
const [one, ...two] = myArray;
// one = 'a', two = ['b, 'c']
Destructuring Objects
Destructuring also works on objects:
const myObject = {
one: 'a',
two: 'b',
three: 'c'
};
// ES6 destructuring example
const {one, two, three} = myObject;
// one = 'a', two = 'b', three = 'c'
In this example, the variable names one
, two
and three
matched the object property names. We can also assign properties to variables with any name, e.g.
const myObject = {
one: 'a',
two: 'b',
three: 'c'
};
// ES6 destructuring example
const {one: first, two: second, three: third} = myObject;
// first = 'a', second = 'b', third = 'c'
Destructuring Nested Objects
More complex nested objects can also be referenced, e.g.
const meta = {
title: 'Destructuring Assignment',
authors: [
{
firstname: 'Craig',
lastname: 'Buckler'
}
],
publisher: {
name: 'SitePoint',
url: 'https://www.sitepoint.com/'
}
};
const {
title: doc,
authors: [{ firstname: name }],
publisher: { url: web }
} = meta;
/*
doc = 'Destructuring Assignment'
name = 'Craig'
web = 'https://www.sitepoint.com/'
*/
This appears a little complicated but remember that in all destructuring assignments:
- the left-hand side of the assignment is the destructuring target — the pattern which defines the variables being assigned
- the right-hand side of the assignment is the destructuring source — the array or object which holds the data being extracted.
Caveats
There are a number of other caveats. First, you can’t start a statement with a curly brace, because it looks like a code block, e.g.
// THIS FAILS
{ a, b, c } = myObject;
You must either declare the variables, e.g.
// THIS WORKS
const { a, b, c } = myObject;
or use parentheses if variables are already declared, e.g.
// THIS WORKS
({ a, b, c } = myObject);
You should also be wary of mixing declared and undeclared variables, e.g.
// THIS FAILS
let a;
let { a, b, c } = myObject;
// THIS WORKS
let a, b, c;
({ a, b, c } = myObject);
That’s the basics of destructuring. So when would it be useful? I’m glad you asked
Destructuring Use Cases
Easier Declaration
Variables can be declared without explicitly defining each value, e.g.
// ES5
var a = 'one', b = 'two', c = 'three';
// ES6
const [a, b, c] = ['one', 'two', 'three'];
Admittedly, the destructured version is longer. It’s a little easier to read, although that may not be the case with more items.
Variable Value Swapping
Swapping values requires a temporary third variable, but it’s far simpler with destructuring:
var a = 1, b = 2;
// swap
let temp = a;
a = b;
b = temp;
// a = 2, b = 1
// Swap with destructuring assignment
[a, b] = [b, a];
// a = 1, b = 2
You’re not limited to two variables; any number of items can be rearranged, e.g.
// rotate left
[b, c, d, e, a] = [a, b, c, d, e];
Default Function Parameters
Presume we had a function prettyPrint()
to output our meta
object:
var meta = {
title: 'Destructuring Assignment',
authors: [
{
firstname: 'Craig',
lastname: 'Buckler'
}
],
publisher: {
name: 'SitePoint',
url: 'https://www.sitepoint.com/'
}
};
prettyPrint(meta);
Without destructuring, it’s necessary to parse this object to ensure appropriate defaults are available, e.g.
// Default values
function prettyPrint(param) {
param = param || {};
const
pubTitle = param.title || 'No title',
pubName = (param.publisher && param.publisher.name) || 'No publisher';
return pubTitle + ', ' + pubName;
}
Now, we can assign a default value to any parameter, e.g.
// ES6 default value
function prettyPrint(param = {}) {
but we can then use destructuring to extract values and assign defaults where necessary:
// ES6 destructured default value
function prettyPrint(
{
title: pubTitle = 'No title',
publisher: { name: pubName = 'No publisher' }
} = {}
) {
return pubTitle + ', ' + pubName;
}
I’m not convinced this is easier to read, but it’s significantly shorter.
Returning Multiple Values from a Function
Functions can only return one value, but that can be a complex object or multi-dimensional array. Destructuring assignment makes this more practical, e.g.
function f() {
return [1, 2, 3];
}
const [a, b, c] = f();
// a = 1, b = 2, c = 3
For-of Iteration
Consider an array of book information:
const books = [
{
title: 'Full Stack JavaScript',
author: 'Colin Ihrig and Adam Bretz',
url: 'https://www.sitepoint.com/store/full-stack-javascript-development-mean/'
},
{
title: 'JavaScript: Novice to Ninja',
author: 'Darren Jones',
url: 'https://www.sitepoint.com/store/leaern-javascript-novice-to-ninja/'
},
{
title: 'Jump Start CSS',
author: 'Louis Lazaris',
url: 'https://www.sitepoint.com/store/jump-start-css/'
},
];
The ES6 for-of is similar to for-in
, except that it extracts each value rather than the index/key, e.g.
for (const b of books) {
console.log(b.title + ' by ' + b.author + ': ' + b.url);
}
Destructuring assignment provides further enhancements, e.g.
for (const {title, author, url} of books) {
console.log(title + ' by ' + author + ': ' + url);
}
Regular Expression Handling
Regular expressions functions such as match return an array of matched items, which can form the source of a destructuring assignment:
const [a, b, c, d] = 'one two three'.match(/\w+/g);
// a = 'one', b = 'two', c = 'three', d = undefined
Further Reading
- Destructuring Assignment – MDN
- Is there a performance hit for using JavaScript Destructuring – Reddit
- the
for...of
Statement – MDN