ES6 - Understanding Destructuring

Subscribe to my newsletter and never miss my upcoming articles

Cover Photo by Michał Parzuchowski on Unsplash

Introduction

Destructuring is a very powerful feature that was introduced with the ES6 version of JavaScript. This article will provide a comprehensive overview of everything that you'll need to know about Destructuring.

Why Destructuring?

If you have been coding in JavaScript, you would have come across scenarios where you would have to access nested objects. Especially, this is true in the case when integrating your application with third-party APIs. You will often have to work with the JSON response received from the API and the object structure is often complex with nested elements.

Accessing the complex nested elements of objects is precisely 'Why' we should use destructuring. It provides a way to simplify the extraction of complex structures.

Let us take a look at the following code example:

//Employee Variable containing nested address for Home and Work
const employee = {
  name: 'Skay',
  age: 32,
  address: {
      line1: '1480 Rachel Garden',
      city: 'Pine Brook',
      state: 'NJ',
      country: 'USA',
  }
};

//Function displays the Home Address individually
function displayHomeAddress(employee) {
    console.log(`The name of the employee is ${employee.name}`);
  console.log(`The Home Address line 1 is ${employee.address.line1}`);
  console.log(`The Home City is ${employee.address.city}`);
  console.log(`The Home State is ${employee.address.state}`);
  console.log(`The Home Country 1 is ${employee.address.country}`);
}

//Call the displayHomeAddress() function
displayHomeAddress(employee);

/*
The name of the employee is Skay
The Home Address line 1 is 1480 Rachel Garden
The Home City is Pine Brook
The Home State is NJ
The Home Country 1 is USA
*/

Two main things to observe from the above code example:

  1. The way to access the values inside nested objects leads to more code being typed at each point of access.
  2. The probability of having a typo is more while trying to type out longer sentences to access nested elements inside the object.

While this might not seem much of a problem with a single file, typically in a real-life project with the large codebase, you'll be dealing with a lot of nested objects and with the destructuring the same can be achieved with a much simpler, compact syntax.

What is Destructuring?

phil-sheldon-abipp-Xpihv46a5bc-unsplash.jpg

*Photo by Phil Sheldon on Unsplash]

In JavaScript, while using objects & arrays, we would often have to deal with complex structures. Destructuring is the process of breaking down such complex structures into simpler parts.

Using destructuring, the above code snippet, will look like this:

const employee = {
  name: 'Skay',
  age: 32,
  address: {
      line1: '1480 Rachel Garden',
      city: 'Pine Brook',
      state: 'NJ',
      country: 'USA',    
  }
};

// Object Destructuring - The left hand side represents the elements that need to be extracted from the parent element
// The right hand side references the parent complex element from which values need to be extracted
const { name } = employee;
const { line1, city, state, country } = employee.address;

function displayHomeAddress(employee) {
  console.log(`The name of the employee is ${name}`);
  console.log(`The Home Address line 1 is ${line1}`);
  console.log(`The Home City is ${city}`);
  console.log(`The Home State is ${state}`);
  console.log(`The Home Country 1 is ${country}`);
}

displayHomeAddress(employee);

/*
The name of the employee is Skay
The Home Address line 1 is 1480 Rachel Garden
The Home City is Pine Brook
The Home State is NJ
The Home Country 1 is USA
*/

Couple of things to note:

  • The element to be extracted has to be placed in between curly parentheses {}.
  • Destrucutring syntax can be expressed as { elementTobeExtracted } = 'parentElement' . Where the elementTobeExtracted must be a direct child of the Parent Element.
  • In the above example, 'name' is a direct child of the 'employee' element. Likewise, the variables 'line1', 'city', 'state', and 'country' are direct children of the element 'address' which is accessed using the dot operator. (employee.address)

Object Destructuring

The above code snippet was an example of object destructuring. Let us look at another example, so that, we can really reinforce the concepts.

//Person object - Simple (No nesting)
const person = {
  name: 'Skay',
  age: 38,
  skills: 'JavaScript',
};

// Object Destructuring
const { name, age, skills } = person;

//Display the output to the console
console.log(name, age, skills);

//Output -> Skay 38 JavaScript

As we have seen above, the left-hand side is an assignment expression where we have used an object literal to extract the direct child elements from the parent element person.

Let us take another code example, where we can use object destructuring for variable assignment.

//Employee Object containing the name, age and skills as atrributes
const employee = {
  name: 'John',
  age: 25,
  skills: 'HTML CSS',
};

// Object Destructuring - It is assigned to a 'let' and not a 'const' for reassignment
let { name, age, skills } = employee;

//Display the output to the console
console.log(name, age, skills);

//Output -> John 25 HTML CSS

//Employee Object also containing the name, age and skills as atrributes
const person = {
  name: 'Skay',
  age: 38,
  skills: 'JavaScript',
};

// Object Destructuring - Reassigning the 'name' 'age' and 'skills' to the new values extracted from person object
({ name, age, skills } = person);

//Display the output to the console
console.log(name, age, skills);

//Output -> Skay 38 JavaScript

Things to note:

  • Initially, the values 'name', 'age', and 'skills' were destructured from the 'employee' object.
  • The desturctured values were assigned to the variables (let) name, age, and skills.
  • Immediately, again using destructuring we have extracted the values name, age, and skills from the 'person' object and reassigned to the 'name', 'age', 'skills' variables.
  • The use of enclosing parentheses (()) in the assignment expression of 'name', 'age', and 'skills' was necessary, since, we are doing an assignment operation. If omitted, the destructuring object literal will be considered as a block statement and will throw an error.
  • To summarize, we have reassigned new values to the local variables name, age, and skills through destructuring.

Default Values

We can assign default values to variables while destructuring. Failing to do so, will cause the value 'undefined' to be assigned to the destructured variable.

const person = {
  name: 'Skay',
  age: 38
};

// Assign default value of Canada to country if undefined
const { name, age, country = 'Canada' } = person;

// Here I am using ES6 template literals
console.log(`I am ${name} from ${country} and I am ${age} years old.`);

// Output -> I am Skay from Canada and I am 38 years old.'

In the above example, 'country' was not defined with the 'person' object and it was assigned a default value of 'Canada' during destructuring.

However, if an actual value is passed for 'country' to the 'person' object, then the default value will not be displayed as shown in the code snippet below.

const person = {
  name: 'Skay',
  age: 38,
    country: 'India'
};

// Assign default value of Canada to country if undefined
const { name, age, country = 'Canada' } = person;

// Here I am using ES6 template literals
console.log(`I am ${name} from ${country} and I am ${age} years old.`);

// Output -> I am Skay from India and I am 38 years old.'

Using Different Variable Names while Destructuring

In the examples we've seen so far, we've used the variable names match the corresponding object key. However, it is possible to use a different name for variables during destructuring using the following syntax.

Syntax for using different variable name → [object_key] : [variable_name]

Let us look at the below code example:

const person = {
  name: 'Skay',
  age: 38,
    country: 'India'
};

// Assign default value of Canada to country if undefined
const { name: fullName, age: years, country: place = 'Canada' } = person;

// Here I am using ES6 template literals
console.log(`I am ${fullName} from ${years} and I am ${place} years old.`);

// Output -> I am Skay from India and I am 38 years old.'

Things to note:

  • The variables 'name', 'age', and 'country' were extracted from the object person and were assigned to 'fullName', 'years', and 'country' respectively.
  • Default value assignment is used in conjunction with assigning to a different variable.

Nested Object Destructuring

If we look at the first example in this article, we had the employee object with an address field that contained nested elements.

In the example, I had demonstrated the usage of destructuring through two individual lines of code as shown below:

const { name } = employee;
const { line1, city, state, country } = employee.address;

We can combine the destructuring in a single line as shown below. This is referred to as Nested Destructuring.

const {  name, address: { line1, city, state, country } } = employee;

Here's the complete code snippet that you can run for the nested destructuring scenario.

//Employee Object containing nested elements
const employee = {
  name: 'Skay',
  age: 32,
  address: {
    line1: '1480 Rachel Garden',
    city: 'Pine Brook',
    state: 'NJ',
    country: 'USA'
  },
};

// Nested Object Destructuring - Use the child element 'address' as a reference 
// to further destructure to get nested inner elements line1, city, state & country
const {  name, address: { line1, city, state, country } } = employee;

function displayHomeAddress(employee) {
  console.log(`The name of the employee is ${name}`);
  console.log(`The Home Address line 1 is ${line1}`);
  console.log(`The Home City is ${city}`);
  console.log(`The Home State is ${state}`);
  console.log(`The Home Country 1 is ${country}`);
}

displayHomeAddress(employee);

I think with this, we've covered all that this there related to Object destructuring. Let us dive into Array destructuring.

Array Destructuring

Array destructuring is very similar to object destructuring. Let us look at the below example.

// A const representing rgb
const animal = ['cat', 'dog', 'rat'];

// Array Destructuring
const [cat, dog, rat] = animal;

//Display the value of R, G, B on the console
console.log(`${cat}, ${dog}, ${rat}`); 

// Output -> cat, dog, rat

Things to note:

  • The variables cat, dog, and rat have been assigned the values of 'cat', 'dog' and 'rat' through array destructuring of the animal array.
  • Each variable is mapped to the corresponding item at the same index on the 'animal' array.

Default Values

Exactly like how we do default value assignment to Object destructuring, we can do for array destructuring as well.

// A const representing rgb
const animal = ['cat', 'dog'];

// Array Destructuring - Default value assignment
const [cat, dog, rat = 'rat'] = animal;

//Display the value of R, G, B on the console
console.log(`${cat}, ${dog}, ${rat}`);

// Output -> cat, dog, rat

In the above example, the variable 'rat' has been set a default value of 'rat' at the step of destructuring.

Destructure selected elements from the Array

We can use the power of destructuring to select a specified set of elements from an array. Let us look at another code example.

//Numbers array
const numbers = [100, 200, 300, 400, 500];

//Skip the elements that you do not want to extract
const [, , three, four] = numbers;

//Display on the console
console.log(three, four);

//Output -> 300 400

In the above example, we can skip the elements that we do not want to extract from the parent array. We used a comma separator to omit the first, second, and last items in the array.

Nested Array Destructuring

christophe-ferron-p0hjjT1O_J8-unsplash.jpg

Photo by Christophe Ferron on Unsplash

Just like how we were able to do a nested destructuring of objects, we can do the same with the arrays as well. Let us look at the below code example.

//Const Color contains hex code and a nested array of rgb values
const color = ['#FF00FF', [255, 0, 255]];

// Use nested destructuring to assign red, green and blue
const [hex, [red, green, blue]] = color;

console.log(hex, red, green, blue); 
//Output -> #FF00FF 255 0 255

In the above example, the rgb values are nested arrays and similar to object destructuring, using the square parentheses, we are able to access elements nested inside the parent.

Mixed Destructuring

Let us combine the power of both object & array & nested destructuring which might be the case if you are dealing with complex objects like the example shown below:

//Const Person contains nested elements of objects & arrays
const person = {
  name: 'Skay',
  location: {
    city: 'Mumbai',
    country: 'India',
    latlong: [19.07609, 72.877426],
  },
};

// We are assigning 5 variables: name, country, city, lat, lng
// We are combining object, nested object & array destructuring in a single line
const {
  name,
  location: {
    city,
    country,
    latlong: [lat, lng],
  },
} = person;

console.log(
  `I am ${name} from ${city}, ${country}. Latitude(${lat}), Longitude(${lng})`
);

// Output -> I am Skay from Mumbai, India. Latitude(19.07609), Longitude(72.877426)

Things to note:

  • 'name' variable is assigned by using object destructuring. It is a direct child of the 'person' object.
  • The variable 'city', 'country', and 'latlong' are accessed using nested destructuring.
  • The 'latlong' within the 'person' object is an array that is further destructured using the array destructuring syntax and assigned to the 'lat' and 'long' variables.

Function Destructuring - Applied to the parameters passed in

For folks who have used React and who will get into learning ReactJS, this is one thing you'll observe quite a bit. We can apply destructuring to the parameters of a function as shown in the code example below.

//Employee Object containing nested elements
const employee = {
  name: 'Skay',
  age: 38,
  skills: {
    languages: 'JavaScript, HTML, CSS',
    databases: 'MySQL, PostgreSQL, MongoDB',
  },
};

//The person object is destructured within the parameters of the function that is passed in
//We have used both object & nested object destructuring within the function parameters
function displayEmployeeInfo({ name, age, skills: { languages, databases } }) {
  console.log(
    `The employee name is ${name} & his age is ${age}. He knows the following languages - ${languages} and is familiar with the databases - ${databases}`
  );
}

//We are invoking the function displayEmployeeInfo & passing in the 'employee' object
displayEmployeeInfo(employee);
//Output -> The employee name is Skay & his age is 38. He knows the following 
//languages - JavaScript, HTML, CSS and is familiar with the databases - MySQL, 
//PostgreSQL, MongoDB

In the above example, the 'employee' object is destructured (nested destructuring is also applied) within the parameters of the function 'displayEmployeeInfo' and the variable name, age, languages & databases are assigned.

An important thing to note that if the 'destructured parameter' is omitted, it'll throw an error. In the above example, if we invoke the displayEmployeeInfo() without passing the employee object, it'll throw an error.

//Invoking the displayEmployeeInfo() without a function will output the error
displayEmployeeInfo();

//Output -> Uncaught TypeError: Cannot destructure property 'name' of 'undefined' as 
//it is undefined.

We can assign a fallback object literal as a default value to handle the error. So, the above code example would need to be modified below to handle the function being invoked without a parameter.

//Employee Object
const employee = {
  name: 'Skay',
  age: 38,
  skills: {
    languages: 'JavaScript, HTML, CSS',
    databases: 'MySQL, PostgreSQL, MongoDB',
  },
};

//Object destructuring and nested object destructuring with default value of object literal
function displayEmployeeInfo({
  name,
  age,
  skills: { languages, databases } = {},
} = {}) {
  console.log(
    `The employee name is ${name} & his age is ${age}. He knows the following languages - ${languages} and is familiar with the databases - ${databases}`
  );
}

//Invoke the displayEmployeeInfo() without passing in the employee object
displayEmployeeInfo();

//Output -> The employee name is undefined & his age is undefined. 
//He knows the following languages - undefined and is familiar with the databases - undefined

Assigning the default object literal '{}' will handle the function call gracefully.

Conclusion

I think we've covered all that is there to know about destructuring in JavaScript. I think it's a powerful feature that improves maintainability and readability. In addition, it reduces the repetition of typing long statements to access nested variables.

To summarize, we have gone through the following concepts of destructuring in this article:

  • Object Destructuring
  • Nested Destructuring
  • Array Destructuring
  • Function Destructuring
  • Mixed Destructuring

I hope you enjoyed the article. Do connect with me on Twitter @skaytech

You may also be interested in the following:

Victoria Lo's photo

Nice one! Very well-written and clearly explained :)

Show +1 replies
Victoria Lo's photo

😂😂 Skay LOL I only read 3 today! It's not a lot. Bookmarked a few too~

Samuel Bouaroua's photo

nice article but IMO, illustration is not a good choice, this is the jew holocaust memorial in Berlin..

Skay's photo

Samuel Bouaroua- I'm sorry, I was not aware of it. I have replaced the Cover Image of the article. Thanks for bringing it to my attention.

Samuel Bouaroua's photo

thank you for your article :) Skay

Bolaji Ayodeji's photo

Well written Skay, thanks for sharing!