The complete guide to destructuring in JavaScript

The complete guide to destructuring in JavaScript

Keep your code dry and clean using destructuring

Siddharth Shyniben
·Oct 27, 2021·

5 min read

Subscribe to my newsletter and never miss my upcoming articles

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

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');

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

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]);

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');

Or even existing variables:

let full, short;

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

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

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

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'];

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
const [name = 'Anonymous'] = ['John'];
name; //=> John

Nesting

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

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

const [[name]] = arr;
name; //=> 'John'

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

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

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;
// ...

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)

Just like in arrays, we can set defaults:

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

We can even mix default values and aliases:

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

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}

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};

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);
}

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});

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 :(

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;

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!

 
Share this