Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / ES6

JavaScript Destructuring: It's So Cool

5.00/5 (21 votes)
14 Aug 2017CPOL7 min read 18.1K   57  
This article discusses about one of the coolest features of ECMAScript 6, i.e., Destructuring

Why are We Here?

It's dead simple. We are here to learn about an ECMAScript 6 (ES6) feature called Destructuring. You know ECMAScript 6 (ES6) right???

Image 1

Well to keep it simple, ECMAScript is a scripting language specification. One of the major implementations of ECMAScript is JavaScript. ECMAScript 6, also known as ECMAScript 2015, is the latest version of the ECMAScript standard. Let's start leaning about one of its major features called "Destructuring" with a story in the next section.

The Magic Box Story

Let's imagine we have a Magic Box.

Image 2

Our magic box has these features:

  • You can put anything inside the magic box
  • You can fill all your items at a time or you can fill whenever you want
  • The magic box can answer your questions about its items.

Well who would not want a magic box like this right?

So let's put some stuff inside the magic box. Let us put:

  • 3 books
  • 5 toys
  • A box of food which contains pizza, chocolate and ice cream
  • A smaller magic box which contains 3 pens and a fruit box which has four fruit items in it (i.e.: apple, mango, banana and grape)

Let's visualize our magic box a bit.

Image 3

Now that we have some items inside the magic box, let's ask it some questions. Suppose we have ten people who are asking a distinct question to the magic box. Let the questions be:

  1. How many books do you have?
  2. How many toys do you have?
  3. What is the first food item?
  4. What is the second food item?
  5. What is the third food item?
  6. How many pens do you have inside the small magic box?
  7. What is the first fruit item inside the small magic box?
  8. What is the second fruit item inside the small magic box?
  9. What is the third fruit item inside the small magic box?
  10. What is the fourth fruit item inside the small magic box?

The magic box says, "I can answer all your questions but only one at a time".

Well, it's fine, but what if it could give all answers at a time?


Do You Feel Bored? Come on! The article just started and you feel sleepy! :)

Image 4

The reason I am boring you with this magic box story is, JavaScript object construction is very much flexible like the magic box. You can put anything you want like string, array, function, other objects, etc. you can create the object all at a time or can assign property any time you want. JavaScript's flexibility is well documented and widely known so let's not get into details of that. But what about extracting properties from object?! Well, until ECMAScript 6 (ES6) arrived, JavaScript had some limitations just like our magic box. To understand this, let us create our sample magic box object in JavaScript.

JavaScript
var magicBox = {
    book: 2,
    toy: 5,
    foodBox: ['pizza', 'chocolate', 'ice cream'],
    smallMagicbox: {
        pen: 3,
        fruits: ["apple","mango", "banana","grape"]
    }
};

Now let's try to get the answers that we asked the magic box. In JavaScript, it will look something like this:

JavaScript
/*ECMAScript 5 (ES5) Statements for extracting certain value*/
var book = magicBox.book;
var toy = magicBox.toy;
var firstFoodItem = magicBox.foodBox[0];
var secondFoodItem = magicBox.foodBox[1];
var thirdFoodItem = magicBox.foodBox[2];

var pen = magicBox.smallMagicbox.pen;
var firstFruitItem = magicBox.smallMagicbox.fruits[0];
var secondFruitItem = magicBox.smallMagicbox.fruits[1];
var thirdFruitItem = magicBox.smallMagicbox.fruits[2];
var fourthFruitItem = magicBox.smallMagicbox.fruits[3];

This is how we have been coding for a long time. Well, not any more. ES6 is our savior with its awesome feature called Destructuring. It gives us the ability to bind properties to as many variables as we need and it works with both Arrays and Objects. We will discuss this in the next section. We will learn step by step how we can extract all the properties in a single line rather than 10 separate statements.

How It Works?

Let's say we want to extract books and toys count from the magicBox object. With ES6 destructuring, we do it like this:

JavaScript
var magicBox = {
    book: 2,
    toy: 5,
    foodBox: ['pizza', 'chocolate', 'ice cream'],
    smallMagicbox: {
        pen: 3,
        fruits: ["apple", "mango", "banana", "grape"]
    }
};
var {book, toy} =  magicBox; /*extracting property value with matched property name;*/
console.log(book); //2
console.log(toy); //5

Let's take a look at this line:

JavaScript
var {book, toy} = magicBox;

The left side of the assignment is known as object pattern. Here, we have to give the same name as object property inside curly bracket. This will assign the magixBox object's matched property values to variables with the same name within parent scope.

Now one may say:

Oh come on! I don't want my variables to have the same name as the object property.

Image 5

Well, destructuring has a solution for this as well. To assign values to a separate named variable, we have to write it like this:

JavaScript
var magicBox = {
    book: 2,
    toy: 5,
    foodBox: ['pizza', 'chocolate', 'ice cream'],
    smallMagicbox: {
        pen: 3,
        fruits: ["apple", "mango", "banana", "grape"]
    }
};
/*assigning to different named variable;*/
var {book: numberOfBooks, toy: numberOfToys} =  magicBox; 
console.log(numberOfBooks); //2
console.log(numberOfToys); //5

The above code matches the property name "book" and "toy", then assigns the value to variable "numberOfBooks" and "numberOfToys" respectively.

With destructuring, we can pull as deep as we want into an object and extract its property value.

JavaScript
var magicBox = {
    book: 2,
    toy: 5,
    foodBox: ['pizza', 'chocolate', 'ice cream'],
    smallMagicbox: {
        pen: 3,
        fruits: ["apple", "mango", "banana", "grape"]
    }
};
var {smallMagicbox: {pen}} =magicBox; //pull deep
console.log(pen);  //3

The above code demonstrates how we can extract value from smallMagicbox object inside our magicBox object.

Now let's take a look at how we can extract values from array.

JavaScript
var numbers = [1,5,9,7];
var [a,b,c,d] = numbers; /*assign array values to variables*/
console.log(a); //1
console.log(b); //5
console.log(c); //9
console.log(d); //7

The left side of this assignment var [a,b,c,d] = numbers; is known as array pattern. Values are assigned to variables according to their index.

Now let's try to extract values from our magicBox food array.

JavaScript
var magicBox = {
    book: 2,
    toy: 5,
    foodBox: ['pizza', 'chocolate', 'ice cream'],
    smallMagicbox: {
        pen: 3,
        fruits: ["apple", "mango", "banana", "grape"]
    }
};
/*getting values from our magicBox's foodBox array*/
var { foodBox:[firstFoodItem, secondFoodItem, thirdFoodItem] } =  magicBox; 
console.log(firstFoodItem); //pizza
console.log(secondFoodItem); //chocholate
console.log(thirdFoodItem);  //icecream

Also we can deep pull the smallMagicbox fruit array like this:

JavaScript
var magicBox = {
    book: 2,
    toy: 5,
    foodBox: ['pizza', 'chocolate', 'ice cream'],
    smallMagicbox: {
        pen: 3,
        fruits: ["apple", "mango", "banana", "grape"]
    }
};
/* pull deep*/
var {smallMagicbox: 
{fruits: [firstFruitItem,secondFruitItem, thirdFruitItem,fourthFruitItem ]} } = magicBox;
console.log(firstFruitItem); //apple
console.log(secondFruitItem); //mango
console.log(thirdFruitItem); //banana
console.log(fourthFruitItem); //grape

Now that we understand how to extract properties with destructuring, let's try to extract all the magicBox properties at once.

JavaScript
var magicBox = {
    book: 2,
    toy: 5,
    foodBox: ['pizza', 'chocolate', 'ice cream'],
    smallMagicbox: {
        pen: 3,
        fruits: ["apple", "mango", "banana", "grape"]
    }
};
/*extracting magicBox values in a single line*/
var {book, toy, foodBox: [firstFoodItem, secondFoodItem, thirdFoodItem], 
     smallMagicbox:{pen, fruits: [firstFruitItem,secondFruitItem, thirdFruitItem,fourthFruitItem ]}} 
     =magicBox;
console.log(book); //2
console.log(toy); //5
console.log(pen); //3
console.log(firstFoodItem); //pizza
console.log(secondFoodItem); //chocolate
console.log(thirdFoodItem); //ice cream
console.log(firstFruitItem); //apple
console.log(secondFruitItem); //mango
console.log(thirdFruitItem); //banana
console.log(fourthFruitItem); //grape

Cool, isn't it?

Image 6

Our magic box may not answer all the questions at a time but with ES6, JavaScript has overcome its limitation. In the next section, we will learn more about the features and usage of destructuring.

Features and Usage

Just like an object returns undefined if it does not contain a property, destructuring does the same when we try to find a property which does not exist. For example, if we try to extract a "basketball" property from our magicBox object, it will return undefined as it does not have any property called "basketball".

JavaScript
var magicBox = {
    book: 2,
    toy: 5,
    foodBox: ['pizza', 'chocolate', 'ice cream'],
    smallMagicbox: {
        pen: 3,
        fruits: ["apple", "mango", "banana", "grape"]
    }
};
var {basketball} = magicBox;
console.log(basketball); //undefined

Similarly, if you try to get a deeply nested property which does not exist, it will give exception.

JavaScript
magicBox.movieBox.SpiderMan /*this gives exception*/
var {movieBox:{SpiderMan}}= magicBox; /*similarly this gives exception in destructuring*/

If the pulled property is undefined, we can assign default value. So when we tried to find the "basketball" property inside magicBox and if it is not found, we can simply assign something to the "basketball" variable.

JavaScript
var magicBox = {
    book: 2,
    toy: 5,
    foodBox: ['pizza', 'chocolate', 'ice cream'],
    smallMagicbox: {
        pen: 3,
        fruits: ["apple", "mango", "banana", "grape"]
    }
};
var {basketball= "Big Basketball"} = magicBox;
console.log(basketball); /*Big Basketball*/
var {basketball:bs= "Big Basketball"} = magicBox; /*You can alias and assign like this*/
console.log(bs); /*Big Basketball*/

One of the coolest features of destrucuring is swapping variable values without the need of the third variable.

Previously, we swapped like this:

JavaScript
var book = 2;
var toy =5;
var aux = book; //auxiliary variable
book = toy;
toy = aux;

using destructuring, we can easily swap like below without the need of auxiliary variable:

JavaScript
var book = 2;
var toy =5;
[toy,book] = [book,toy];
console.log(book); //5
console.log(toy); //2

We can pull values using computed property names. Let's look at an example of ES5:

JavaScript
var propName = "book";
var magicBox = {book: 5};
var numberOfBooks = magicBox[propName]; /*instead of directly using magicBox["book"] 
                                         we are using a computed peoperty*/

In ES6, we can achieve this same result but we will need one statement less.

JavaScript
var propName = "book";
var {[propName]: numberOfBooks }= {book: 5};
console.log(numberOfBooks ); //5

In terms of arrays, we can skip values and only take which we want like below:

JavaScript
var [,a,,b,c] = [1,2,3,4,5]
console.log(a); //2
console.log(b); //4
console.log(c); //5

There is a rest operator(...) to assign remaining array values to a variable:

JavaScript
var [a,...b] = [1,2,3,4,5];
console.log(a); //2
console.log(b); //[2,3,4,5]

Destructuring comes in really handy when we want to get some returned value from a function.

JavaScript
function getMember(){
   return {
        name : "Jonh",
        age: 25
   };
}
var {name,age} = getMember();
console.log(name); //John
console.log(age); //25

We can use default values for function parameter.

JavaScript
function sum({num1=0, num2=0}){
   return num1+num2;
}
var result= sum({num2: 5});
console.log(result); //5
result = sum({});
console.log(result); //0

If we want to make the whole parameter object optional, then we write it like this:

JavaScript
function sum({num1=0, num2=0}={}){
return num1+num2;
}
result = sum();
console.log(result); //0

There are two levels of default value assignment here. Once there is no parameter passed, the function parameter is set to empty object. Again, when no property is found in empty object, num1 and num2 then set to 0;

One of the powerful features of ES6 is For of iteration with destructuring. Let's take a look at the example below:

JavaScript
var employeeList = [{
        name: 'John',
        department: {
            name: 'Finance',
            managerName: 'Steve'
        }
    },
    {
        name: 'Mark',
        department: {
            name: 'Humar Resource',
            managerName: 'David'
        }
    }
]
for({name: n, department:{name: d, managerName: m }} of employeeList){
console.log("Name:" +n);
console.log("Department:" +d);
console.log("ManagerName:" +m);
}

Notice how easily we are iterating the list and extracting the values we need in a single go. Just imagine the hassle we had to take previously to retrieve the three properties. Something like this:

JavaScript
for(var i=0;i<employeeList.length;i++)
{
   var n= employeeList[i].name;
   var d= employeeList[i].department.name;
   var m= employeeList[i].department.manager;
}

That's all for this article. All the examples are included in the download file. You can easily check from there as well. Did you like the features of destructuring? Like it or not, this will be highly used in JavaScript programming in the near future. Therefore, I would suggest you start learning more about destructuring and other features of ECMAScript 6.

Quick Tip For Practise

Just open a latest Google Chrome browser. Go to https://jsfiddle.net/. On the JavaScript section, copy paste the code and press run. See the result in browser console. Enjoy! :)

Image 7

Conclusion

ECMAScript 6 (ES6) is still not fully supported by all modern browsers, but it will eventually be adopted everywhere. This is the way how JavaScript will be coded in the near future. Therefore, it is the perfect time for us to get familiar with its features. Destructuring is one of its coolest features.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)