Andy Crouch - Code, Technology & Obfuscation ...

JavaScript Destructuring Syntax

Photo: Unsplash - Markus Spiske

JavaScript has the destructuring assignment syntax to allow you to unpack objects and arrays into variables. I still see a lot of code where either the developer is not aware of this language feature or just didn’t use it. The feature was added in ES6 and enables more terse code without the lose of intent. What follows is a whistle-stop tour of the syntax and how to use it.

Array Destructuring

Array destructuring allows you to define variables based on the position of elements in an array. A simple example is:

const numbers = [1,2,3,4];
const [ one, two, three, four ] = numbers;
const [ a,,e,g ] = numbers;

console.log(one);
console.log(two);
console.log(three);
console.log(four);

console.log(a);
console.log(e);
console.log(g);

To destructure array values you will see that the variables are defined by declaring them in a set of square brackets. They are defined in the order they will be mapped to against the array elements. If the variables do not already exist then you need to prefix the declaration with a let or const. As the position is used to destructure the values from the array you need to handle the position of values you do not want. You will see there is an empty space declared in the a,e and g destructuring.

If you are interested in the first couple of elements in the array then you can apply a “rest” pattern and combine the remaining elements into a single variable. This is achieved by prefixing the final variable declared with three periods as shown in the example below:

const numbers = [1,2,3,4];
const [ one, two, ...remainder ] = numbers;

console.log(one);
console.log(two);
console.log(remainder);

You can us this array destructuring approach with iterables as shown below:

function* makeRangeIterator(start = 0, end = 100, step = 1) {
    let iterationCount = 0;
    for (let i = start; i < end; i += step) {
        iterationCount++;
        yield i;
    }

    return iterationCount;
}

var [first, second, third, fourth, fifth, sixth, ...rest] = makeRangeIterator();
console.log(sixth);
console.log(rest);

Object Destructuring

Destructuring objects works in a near-identical manner to what we have seen above. Instead of a variable being bound on position, they are bound to object properties as shown below:

const person = {
    firstName: "Donald",
    lastName: "Duck",
    age: "105",
    address:{
         houseNumber: "14446",
         street: "Looney Road",
         town: "Loonery Town"
    }
}

const { firstName: first_name, lastName: last_name } = person;

console.log(first_name);
console.log(last_name);

An even clearer approach is to use the provided shortcut which works if you name the variables the same of the properties such as:

const person = {
    firstName: "Donald",
    lastName: "Duck",
    age: "105",
    address:{
         houseNumber: "14446",
         street: "Looney Road",
         town: "Loonery Town"
    }
}

const { firstName, lastName } = person;

console.log(firstName);
console.log(lastName);

You will notice that instead of square brackets, object destruction used curly brackets to surround the variable declaration.

In order to deconstruct more complex objects such as the address data in the person object you can nest the declaration of variables in line with the structure of the object. You prefix each block of variable destructuring with the name of the parent property and surround their child declarations with further curly brackets as shown below:

const person = {
    firstName: "Donald",
    lastName: "Duck",
    age: "105",
    address:{
        houseNumber: "14446",
        street: "Looney Road",
        town: "Loonery Town"
    }
}

const { address: {houseNumber, street} } = person;

console.log(houseNumber);
console.log(street);

You can nest your destucturing of the data as deeply as you want by continuing the pattern as shown here:

    const person = {
    firstName: "Donald",
    lastName: "Duck",
    age: "105",
    address:{
        houseNumber: "14446",
        street: "Looney Road",
        town: "Loonery Town",
        phones:{
            mobile: "03456789",
            landLine: "23456789"
        }
    }
}

const { address: { houseNumber, street, phones:{ landLine } } } = person;

console.log(houseNumber);
console.log(street);
console.log(landLine);

Destructuring Defaults

If you try to destructure array elements or object properties that don’t exist your variable will be set to undefined as shown below:

const person = {
   firstName: "Donald",
   lastName: "Duck",
   age: "105",
}

const { weight } = person; // <- undefined


console.log(weight);

If you are unsure of the properties you are destructuring you can set default values when declaring the variables such as:

const person = {
    firstName: "Donald",
    lastName: "Duck",
    age: "105",
}

const { firstName, lastName, height = "110" } = person;

console.log(firstName);
console.log(lastName);
console.log(height);

Wrapping Up

Hopefully you can see the benefit of destructuring and how it reduces the number of variable declarations you make to retrieve data from objects and arrays. You can use the syntax in a few ways other than just variable declaration.

You can define a function to accept a single object as a parameter and use the destructuring syntax to pull the actually values from the object that you need such as:

const person = {
    firstName: "Donald",
    lastName: "Duck",
    age: "105",
}

function printNameFor({ firstName, lastName }){
    console.log(firstName);
    console.log(lastName);
}

printNameFor(person);

You can also use the syntax to handle returning multiple values from a function such as:

const person = {
    firstName: "Donald",
    lastName: "Duck",
    age: "105",
}

function getNamesFrom(person) {
    const { firstName, lastName } = person;
    return [ firstName, lastName];
}

const [ firstName, lastName ] = getNamesFrom(person);

console.log(firstName);
console.log(lastName);

If you have any questions around the destructuring syntax then let me know via twitter or email.