DEV Community

Cover image for The complete guide to destructuring in JavaScript
Siddharth
Siddharth

Posted on • Updated on • Originally published at blog.siddu.tech

The complete guide to destructuring in JavaScript

Two commonly used data structures in JavaScript are Object and Array. And many times we may need to extract individual pieces of the object instead of the whole thing. This is where Destructuring comes in.

Destructuring is a special syntax which is used to "destructure" or "unpack" an object or array into many variables, as that may be more useful.

Array destructuring

Here's an example of array destructuring:

const site = ['dev', 'to'];

// destructuring here
let [domain, ext] = site;
// this is basically equal to
// let domain = site[0]
// let ext = site[1]

alert(domain); //=> dev
alert(ext);    //=> to
Enter fullscreen mode Exit fullscreen mode

By using destructuring, we did not have to repeat the array's name or the indices. Destructuring can be really helpful when using string methods which return arrays:

const [firstName, lastName] = 'John Doe'.split(' ');
const [full, short] = /(.+?(?!=day))day/gi.exec('Monday');
Enter fullscreen mode Exit fullscreen mode

Note that the original array does not change when destructuring. Destructuring is not destructive.

Skippping items

You can use holes to skip items in arrays:

const [, lastName] = 'John Doe'.split(' ');

alert(lastName); //=> Doe
Enter fullscreen mode Exit fullscreen mode

Works with any iterables

Actually, we can use any iterable in destructuring (including objects, which we will talk about later)

let [a, b, c] = 'abc'; //=> ['a', 'b', 'c']
let [one, two, three] = new Set([1, 2, 3]);
Enter fullscreen mode Exit fullscreen mode

This is because destructuring is kind of syntactic sugar of using for...of over the Iterable and then assigning the value to variables.

Assign anything

You can assign anything which can be assigned, say object properties:

const day = {};

[day.full, day.short] = /(.+?(?!=day))day/gi.exec('Monday');
Enter fullscreen mode Exit fullscreen mode

Or even existing variables:

let full, short;

[full, short] = /(.+?(?!=day))day/gi.exec('Monday');
Enter fullscreen mode Exit fullscreen mode

The variable swapping trick

There's a common trick which is used to swap two variables using destructuring:

let student = 'You';
let master = 'Me';

[student, master] = [master, student];

student; //=> Me
master; //=> You
// The student has become the master
Enter fullscreen mode Exit fullscreen mode

The rest ...

If an array is longer than what you destructure, the extra items are left out.

const days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];

const [day1, day2] = days;
day1; //=> Sunday
day2; //=> Monday
// No more assignments
Enter fullscreen mode Exit fullscreen mode

You can collect those items using rest parameters:

const days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];

const [
    day1, // First item aka Sunday
    day2, // Second item aka Sunday
    ...restDays // All the other items
] = days;

restDays; //=> ['Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
Enter fullscreen mode Exit fullscreen mode

You can use any name instead of restDays, the only rule is that it should be preceded by three dots and should be last.

Default values

If you destructure nonexistent values, there will be no error. The items will simply be undefined. We can set default values to fix this:

const [name = 'Anonymous'] = [];
name; //=> Anonymous
Enter fullscreen mode Exit fullscreen mode
const [name = 'Anonymous'] = ['John'];
name; //=> John
Enter fullscreen mode Exit fullscreen mode

Nesting

You can also destructure nested arrays. Just use the same syntax inside.

const arr = [["John"]]; // Nested array!

const [[name]] = arr;
name; //=> 'John'
Enter fullscreen mode Exit fullscreen mode

Or a really complex example:

const arr = ['Foo', ['Bar', ['Baz', 'Lol', ['Quux']]]];
const [foo, [bar, [baz, lol, [quux]]]] = arr2;

foo; //=> Foo
bar; //=> Bar
baz; //=> Baz
lol; //=> Lol
quux; //=> Quux
Enter fullscreen mode Exit fullscreen mode

Just note that when you destructure nested items which dont exist, an error will be thrown.

Object destructuring

Objects can also be destructured and the syntax is pretty much the same.

const site = {domain: 'dev', ext: 'to'};

// destructuring here, note the {}
let {domain, ext} = site;
// this is basically equal to
// let domain = site.domain
// let ext = site.ext

alert(domain); //=> dev
alert(ext);    //=> to
Enter fullscreen mode Exit fullscreen mode

Also note the order does not matter:

const rectangle = {
    width: 10,
    height: 20,
    x: 5,
    y: 5
};

// All of these work
const {width, height, x, y} = rectangle;
const {x, width, height, y} = rectangle;
const {y, width, x, height} = rectangle;
// ...
Enter fullscreen mode Exit fullscreen mode

Aliasing

We can set aliases to destructured variables by writing realName: alias just like a normal object:

const rectangle = {
    width: 10,
    height: 20,
    x: 5,
    y: 5
};

const {width: w, height: h, x, y} = rectangle;

w; //=> 10 (value of width)
h; //=> 20 (value of height)
Enter fullscreen mode Exit fullscreen mode

Just like in arrays, we can set defaults:

const name = {first = prompt('First name'), last = prompt('Last name')} = {first: 'John'};
Enter fullscreen mode Exit fullscreen mode

We can even mix default values and aliases:

const name = {first: f = prompt('First name'), last: l = prompt('Last name')} = {first: 'John'};
Enter fullscreen mode Exit fullscreen mode

The rest ...

Just like arrays, objects also can have a rest property.

const coords = {x: 13, y: 42, z: 8};

const {x, ...rest} = coords;

x; //=> 13
y; //=> {y: 42, z: 8}
Enter fullscreen mode Exit fullscreen mode

A quick gotcha for assigning existing values

In the previous examples, we used let {...} = {...} which is fine. But when you try {...} = {...} there will be an error:

let width, height;

// Error here
{width, height} = {width: 10, height: 21};
Enter fullscreen mode Exit fullscreen mode

this is because JavaScript considers {...} on it's own as a block statement. A block statement can be used to group code:

{ // This is a isolated block
    let foo = 42;
    alert(foo);
}
Enter fullscreen mode Exit fullscreen mode

So, to tell JavaScript that we need destructuring, we can wrap it in ():

let width, height;

// This is fine
({width, height} = {width: 10, height: 21});
Enter fullscreen mode Exit fullscreen mode

Nesting

Just like in arrays, we can destructure nested properties too! We just need to mimic the structure of the source

const rect = {
    color: red,
    coords: {
        x: 12,
        y: 7,
    }
};

const {
    color,
    coords: {
        x,
        y,
    }
} = rect;

color; //=> red
x; //=> 12
y; //=> 7
// No coords :(
Enter fullscreen mode Exit fullscreen mode

Note that we have no coords, since we are destructuring it's values.

Here's a complete destructuring example:

const order = {
    items: ['Pizza', 'Donuts'],
    extra: true,
    amount: {
        pizza: 2,
        donuts: 4
    }
};

const {
    items: [main, ...rest] = [], // Array destructuring
    extra = false, // Default props
    amount: { // Nested
        pizza,
        donuts
    },
    homeDelivery = false, // Non existent values
} = order;
Enter fullscreen mode Exit fullscreen mode

That's everything you need to know about destructuring!

If you found this post helpful, spread the word! or follow me on twitter or over here to stay updated on my blog posts!

Discussion (0)