Destructuring Objects in ES6

What is destructuring?

Destructuring is a way to extract values from nested arrays and objects.

When you use destructuring, you are taking a JavaScript expression and extracting data from either arrays, objects, maps, and sets into their own variable. It also allows you to extract properties on an object or items from an array in multiples.

Examples

const car = {
  make: 'Subaru',
  model: 'BRZ',
  year: '2018',
  dealership: 'Cochran',
  city: 'Pittsburgh'
};

const make = car.make;
const model = car.model;

In this example, we have some pretty repetitive code where we need to create a variable from some value inside of an object.

Instead of creating multiple variables, we can destructure them to a single, sweet line:

const { make, model } = car;

where we get a variable called make and a variable called model extract them from the car object and putting them into their own variables which are scoped to the parent block, in this case, the window since they aren’t in a nested object.

If I wanted to add another property to the destructured object, I could do something like this:

const { make, model, year } = car;

where we get a top level variable inside our scope.

This is a good use of destructuring, but what if we want to get at data in nested arrays and objects?

Take this data we get from some web API:

const weather = {
  city: 'Pittsburgh',
  state: 'Pennsylvania',
  local: {
    precipitation: {
      snowing: yes,
      raining: no,
    },
    coordinates: {
      lat: '40.4406° N',
      long: '79.9959° W'
    }
  }
};

I just want the latitude and longitude in this case. I could do:

const lat = weather.local.coordinates.lat;
const long = weather.local.cooridinates.long;

but this is not easy to reason about.

Destructuring to the rescue:

const { lat, long } = weather.local.coordinates;
console.log(lat, long);

In this instance we need to destructure weather.local.coordinates because we are destructuring an object a few levels deep.

Other Fun Stuff

You can also rename and destructure variables in ES6.

How?

const snowing = 'no';
const weather = {
  city: 'Pittsburgh',
  state: 'Pennsylvania',
  local: {
    precipitation: {
      snowing: 'yes',
      raining: 'no',
    },
    coordinates: {
      lat: '40.4406° N',
      long: '79.9959° W'
    }
  }
};

Here I already have a snowing variable. I also have a snowing key on the same object. You aren’t able to do this, however, so you will need to rename the variable or the key within the object. In this instance, we can rename the snowing property to snow and the raining property to rain.

const { snowing: snow, raining: rain } = weather.local.precipitaton;

This will assign weather.local.precipitaton to a variable called snow and also to a variable called rain.

ES6 Modules

ES6 modules allows us to have reusable code, in separate files. We do this to eliminate initially massive js files, like app.js in a Node and Express project. Modules allow us to spread code over relevant files.

Take this students.js file

const students = [‘Peter’, ‘Paul’, ‘Mary’];

export const students = [‘Peter’, ‘Paul’, ‘Mary’];

Export allows us to export functions, objects, and primitive values into another files.

In app.js we import those values as modules into the main js file:

import { students } from ‘./students’;

…where ./students represents the file stored in the same directory as app,js.

Importing More than One Value

You can import more than one value from a module. Take students.js:

export const total = 42;

We can import this variable into app.js along with the students array:

import { students, total } from ‘./students’;

Export Data and Functions Between Files

You can export functions between files, such as in this calc.js file:

const add = (x, y) => {
  return x + y;
}

const divide = (x, y) => {
  return x / y;
}

export { add, divide };

To import this module into app.js:

import { add, divide } from ‘./calc’;

Exports are not just limited to primitive data types.

Export Fallbacks with Default

What if we wanted a function to be the main function for our module?

We can add a default keyword to have a fallback:

export { add, divide };
export default multiply;

This will allow the module to fallback on a function if another fails.

Watch for this Pitfall

It may be tempting to do something like this:

export default const add = (x, y) => {
  return x + y;
}

This will result in a TypeError.

Why?

The default keyword creates a variable called default. Adding default and const simultaneously, JavaScript will try to declare two different variables, which is not allowed in most programming languages.

More to Come

ES6 is the standard now and so I am learning it, as quickly as possible. Let me know some of your favorite features of ES6.