Destructuring in JavaScript

Destructuring is breaking down arrays and objects so the individual elements are easier to use in your code. The main purpose is to make reading and debugging your code easier. The JavaScript run time engine will have no advantage from destructuring. Actually because destructuring assigns new variables with the same values that are already being stored there is a small hit. But the hit is extremely small, and the increase in readability of your code will more then make up for any hit you’ll.

JSPerf has a page that tests out assignments by direct and by destructing, and unless you are doing 100 Million operations per second you won’t notice the difference.

What is destructing replacing?

Let’s take a look at how we handle objects and arrays now.

let myArray = ['Monday', 'Tuesday', 'Wednesday'];
let myObject = { name: 'John', id: 117};

So how would we output the values?

console.log(myArray[0]);      // outputs Monday
console.log(myObject.name);   // outputs John

This isn’t bad, but if we needed to use the myObject.name multiple times in a function if might be useful to reassign it to a new variable.

let name = myObject.name;

And there we go, we pulled it out. Now the idea with destructuring is being able to pull the value out of an array or object in a kind of short hand way.

Assignment

Just so we are all on the same page. The assignment operator = takes whatever value is on the right side and try’s to put it in the variable on left side.

let target = source;

Now normally the left side will have just one variable the trick with destructuring is that there is multiple variables on the left side. Whoa! I couldn’t have said it better, Ted.

And that’s where destructuring steps in.

Array Destructuring

Here we are putting the myArray as the source, and making an array of variables. Okay, it’s not really an array, but it looks like an array. Since it’s on the left side, it’s the assignment’s target.

let [day1, day2, day3] = myArray;

day1 will get the first element [0], day2 will get the second element [1]. And so on.

If the left has more variables then elements the extra variables will get undefined.

What if there is not enough variables on the left side to hold all the elements in the array? The rest of the elements won’t be assigned.

Rest Operator

But with a little help from the rest operator, we can collect the unused elements into a new array.

let [day1, ...days] = myArray;

Just like before day1 will get the element at [0]. The rest operator ... will put the rest of the array into a new array called days.

Ignore Elements

If the element you don’t want is in the middle instead of the end, we can ignore it.

[day1, , day3] = myArray;
console.log(day1);        // Monday
console.log(day3);        // Wednesday

The [1] element containing Tuesday has been ignored.

Default values

let shortArray = [2, 3];
[a=1, b=2, c=7] = shortArray;

Here we are setting default values. If shortArray was an empty array, a would still get 1, b would get 2 and c would get 7. By using default values we ensure that each variable will be defined with a value.

More Examples

Here we are assigning 1 and 2 to a and b:

let a, b;

[a, b] = [1, 2];

Swapping variables are quick one liners.

let a=5;
let b=10;

[a, b] = [b, a];

console.log(a);     //   10
console.log(b);     //   5

Destructuring arrays when calling functions

A very useful place to use destructing when calling a function. Let’s say we have a function that we want to pass an array to but once in the function we want to use the elements separately. This might be an options array.

let myArray = ['John', 117, Earth];
function displaySpartan([name, id, planet]){
    console.log(`${name}, ${id}, is from ${planet}`);
}
displaySpartan(myArray);    // John, 117, is from Earth

Object destructuring

Arrays are destructured based on the order of the elements. Objects are key value pairs, so they have names. We can destructure very objects and grab only the elements we want.

let myObject = {name: 'John', id: 117, planet: 'Earth'};

So how do we destructure an object? Well, just like the array we’ll create a target object on the left side that will take the values from the source.

let {name, id, planet} = myObject;

console.log(name);      // John
console.log(id);        // 117
console.log(planet);    // Earth

Unlike the array, the object doesn’t need to be in the same order.

let {planet, name, id} = myObject;

console.log(name);          // John
console.log(id);            // 117
console.log(planet);        // Earth

Using new names

The names match up and pass the values through. So what if we don’t want the same variable names? Well, that’s no problem.

let { planet: p , name: n, id: i } = myObject;

We’re talking the value that is in planet and putting it in p. This is totally optional. If using the same name works, then save the keystrokes and shorten the destructuring call.

Default values

Just like with arrays, we can set default values.

let myObject = {a: 12, b=15};
let {a=1, b=2, c=3};

console.log(a);            // 12
console.log(b);            // 2
console.log(c);            // 3

New names and defaults

And a little more complex, changing the names and setting defaults

let myObject = {a: 12, b=15};
let {a: f=1, b: g=2, c: h=3};

console.log(f);            // 12
console.log(g);            // 2
console.log(h);            // 3

Objects inside of Objects

There will be times when an objects contains another object. And it’s possible to destructure many layers down.

let myStateObject = {
    name: 'Minnesota',
    capital: 'St Paul',
    population: 5679718,
    bird: 'Common Loon',
    NumOfLakes: 11842,
    sportTeams: {
        baseball: 'Twins',
        football: 'Vikings',
        soccer: 'Minnesota United',
        basketball: 'Timberwolves',
        basketballWoman: 'Lynx',
        hockey: 'Wild'
    }
}

To get to the Twins, we’ll need to dig a little. If we need to use this often, it could mean a lot of typing.

let baseballTeam = myStateObject.sportTeams.baseball;
let { sportTeams: { baseball: baseballTeam } } = myStateObject;

console.log(baseballTeam); // Twins

We’re also changing the name to baseballTeam. If we dropped the : baseballTeam a variable named baseball would be made.

Now I’ll grant you that if you only need to call in once, destructuring just for baseball might not be a great help, but if you needed a few elements and reuse them many times, this can make things a lot cleaner.

let {
    name: stateName,
    bird: stateBird
} = myStateObject;

console.log(stateName);      // Minnesota
console.log(stateBird);      // Common Loon

Now if we didn’t want to rename the variables, we can really shorten it. And now you might now see how this can be a shorter way of using objects.

let { name, bird } = myStateObject;

Destructuring into a function

Passing myStateObject into a function would be easier if we destructure the object as is was passing in.

function displayState( {name, population, capital} ) {
    console.log(`${name} has a population of ${population} and it's capital is ${capital}.`);
};

Now we could pass in a stateObject and as long as it had elements name, population, capital it would display just fine. Remember we could add default values as well.

Reason

I started off by saying that destructuring saves you typing and keeps the length of the variables shorter. And that’s all true. Another reason to use destructuring when calling a function is that it’ll clearly tell a reader which parts of the object it’s getting is actually being used.

function displayState( {name, population, capital} ) {
    console.log(`${name} has a population of ${population} and it's capital is ${capital}.`);
};

Let’s compare.

function displayState( myStateObject) {
    console.log(`${myStateObject.name} has a population of ${myStateObject.population} and it's capital is ${myStateObject.capital}.`);
};

In this short example, we can quickly see the three parts of the myStateObject is being used but how about if the function was 25 lines long. Still not hard, but you have to admit with destructuring you don’t have to look in the function, it’s the first line!

Resources

MDN - Destructuring assignment

If you want to learn more about my home state, Minnesota

javascript.info has a lot of examples.