JavaScript: What's New in ECMAScript 6: Part One

In this article you will look at whats changed in ES6. We will look at changes in design patterns from ES5 to ES6.

Introduction

Explaining the whole world of ES6 in one article is impossible or impratical, therefore, this fundamentals of ES6 article  is going to be a compilation of many articles. I am going to post a new article every week. So stay tuned. Every feature is going to be explained by comparing what we used to do before ES6 and what is now standard in ES6. By this technique it will be easy for you to change your old programming habits or you can choose whichever best fits for you.

Before moving to the tutorial, let me tell you that up to this day ES6 is still in heavy development and only modern browsers support the features. But you can always use Transpilers or polyfills to get away with it. I am going to post an article on that too in the future. Enough chatting, lets start.

This is part one of my ES6 Fundamentals training series.

Contents

  • let Keyword
  • const keyword
  • Destructuring
  • Default Parameters
  • Rest Parameter
Let Keyword

Let is simply a replacement for var keyword in javascript. Var had a few problems which are now solved by let. So as per Douglas Crockford (those who don't know him, he is the "Brad Pitt" of the Javascript Community :P. He is badass) "Stop using var and start using let."
 
Why?
 
A var has function scope (it declares a variable that's visible throughout the function) even though it looks like it has block scope, whereas let is scoped to current block. Look at the example

Var: Traditional way
  1. var someMethod = function()  
  2. {  
  3.     var num = 10; // creates a function level scope    
  4.     if (true)   
  5.     {  
  6.         var num = 20; // changes value of num from 10 to 20 even if its in new block    
  7.     }  
  8.     console.log(num);  
  9. }  
  10. someMethod();  
Output

20

In the above code what I created is a variable nuber with value 10 in a function. Now I created a new variable number in if block-scope in a function but, even though both are in different blocks javascript doesn't care, it changed the outer number from 10 to 20.

Now let us see let (no pun intended)

Let: ES6 Way

  1. let someMethod = function()  
  2. {  
  3.     let num = 10;  
  4.     if (true)   
  5.     {  
  6.         let num = 30;  
  7.     }  
  8.     console.log(num);  
  9. }  
  10. someMethod();  
Upon executing the above code, we get,

Output

10

Therefore let uses block scope not function scope variable.

Const keyword

If you have ever coded in java,c,c++,c# you should know the meaning of const.

Const is a type of variable whose value can never be changed. In simple terms, whatever value you assigned to a const variable, it will remain the same throughout the program. If you try to be overly smart and change the value, javascript will return an error. Before ES6 we never had const keyword as ES standards, so no comparison of old syntax with new.

Example
  1. const num = 20;  
  2. if (true)  
  3. {  
  4.     num = 10;  
  5. }  
The above program will produce an error: num is read-only, which means that you cannot change the value of const. Like let, const also has block level scope, so, const specified in outer block will be totally different from variable in inner block.
  1. const num = 20;  
  2. if (true)  
  3. {  
  4.     let num = 10;  
  5.     console.log(num);  
  6. }  
  7. console.log(num);  
Output

10
20

In the above program we created a const variable num in outer scope but in inner scope we re-defined a new variable with same name num with value 10. So console.log in inner scope will return 10 and outer scope log will return 20.

Destructuring assignment

Let's talk about this new cool feature of ES6. If you have ever coded in Python then you must be familiar with the word. For others, destructuring means extracting data from array or objects into variables. This might sound little odd at first, but once you understand how it works you'll want to use it everywhere in your code.

Ok so lets see an example.
  1. let num1 = 10;  
  2. let num2 = 20;  
  3. let arr = [num2,num1];  
  4. [num1,num2] = arr;  
  5.   
  6. console.log(num1 +" "+num2); 
Output

20 10

In the above code, I created two variables num1 and num2 with value 10 and 20. On line 3 I created an array whose first value is num2 (20) and second value is num1 (10). On line 4 I am not creating a new array, instead I am assiging value of num2 into num1 and value of num1 into num2. What is happening behind the scene and what we used to do before ES6 was,
  1. var num1 = 10;  
  2. var num2 = 20;  
  3. var arr = [num2, num1];  
  4. num1 = arr[0];  
  5. num2 = arr[1];  
  6.   
  7. console.log(num1 + " " + num2);  
Instead of specifying each and every variable with its corresponding array index, we simply use destructuring syntax of Javascript to assign the values of array into variables.

We can further refactor our code,
  1. let [num1,num2] = [20,10];  
So we can declare and initialize our variable in a simple line.

Right now we are destructuring an array so we are using [] brackets in declaration but in future when we are going to destructure objects we will use {} instead of [] like let {a, b}. We will talk about that later. But right now focus on array destructuring.

We can also assign a function which returns an array like this,
  1. let returnArray = function()  
  2. {  
  3.     return [20, 10];  
  4. }  
  5.   
  6. let [num1, num2] = returnArray(); 
It will produce the same result.

Now let's say instead of returning an array with size 2 we are returning with a size of 4 elements. What will happen in that case?
  1. let returnArray = function()  
  2. {  
  3.     return [20, 10, 30, 40];  
  4. }  
  5. let [num1, num2] = returnArray();  
  6. console.log(num1, num2);  
Output when logging out num1 and num2 will be,

num1: 20, num2: 10

Now let's look at the next example,
  1. let returnArray = function()  
  2. {  
  3.     return [20, 10];  
  4. }  
  5. let [num1, num2, num3] = returnArray();  
What will be the output of num3 in above code?

It turns out that when we do not return an array with required amount of size, as in this code we are returning 2 values instead of 3 for each variable, the variable without a value will be #ff0000.

This was cool and all but where destructuring really shines in when we are using objects. When we want to initialize a variable from an object's property we can use the power of destructuring.

First let's see an old way of doing it.
  1. var Person =   
  2. {  
  3.     fname: "Sanyam",  
  4.     lname: "Singh",  
  5.     age: "200"  
  6. };  
  7.   
  8. var firstName = Person.fname;  
  9. var lastName = Person.lname;  
  10. var userage = Person.age;  
In the above code Person object has 3 properties fname, lname and age. We created 3 variables firstName, lastName, userage and initialized with the values of Person object properties.

Now let's see the new way of doing it using destructuring.
  1. let Person =   
  2. {  
  3.     fname: "Sanyam",  
  4.     lname: "Singh",  
  5.     age: "200"  
  6. };  
  7. let   
  8. {  
  9.     fname: firstName,  
  10.     lname: lastName,  
  11.     age: userage  
  12. } = Person;  
We'd get the same output as above but in this case we used the power of destructure.

Remember that now we are using {} instead of [] on line 6. One more thing to remember - let {fname: firstName, lname: lastName, age: userage} the left side is the name of property and right side is the name of the new variable, so fname is name of property and firstName is name of our new variable declared.

We can refactor our code a bit more,
  1. let Person =   
  2. {  
  3.     fname: "Sanyam",  
  4.     lname: "Singh",  
  5.     age: "200"  
  6. };  
  7. let  
  8. {  
  9.     fname,  
  10.     lname,  
  11.     age  
  12. } = Person;  
The above code will create 3 new variables with same name of that of property. fname, lname, age

You can now console log your fname, lname and age like so - console.log(fname) and you'll get Sanyam as result. Now you know the basics of destructuring. We can move on to the next topic. If you want some more examples of destructuring with complex objects. Comment below and i'll provide some more examples.

Default Parameter

Default parameters for me is one of the biggest feature of ES6. Seriously, little features like these create a big impact in day to day coding. Default parameters allow function parameters to be initialized with default values if no value or #ff0000 is passed. The what about statement means that if you do pass any value to function argument, your function will assign a default value.

First let's see how we used to do it the old way,
  1. var someMethod = function someMethod(num1, num2)  
  2. {  
  3.     num1 = (num1 === #ff0000) ? 10 : num1;  
  4.     num2 = (num2 === undefined) ? 20 : num2;  
  5.     console.log(num1 + " " + num2);  
  6. };  
  7. someMethod();  
In the above code, someMethod function contains 2 parameters num1, num2. In the definition of function we are checking if num1 or num2 is undefined then use 10 and 20 respectively as default values otherwise use the value passed into num1 and num2 variable. The conditional operator (? : ) is just shorthand of if-else.

Now let's see the ES6 Way,
  1. var someMethod = function(num1 = 10, num2 = 20)  
  2. {  
  3.     console.log(num1 + " " + num2);  
  4. };  
  5. someMethod();  
See how simple it is? We just passed default values in function parameter using = operator. So output will be 10 and 20.

Rest Parameter

The rest parameter syntax allows us to represent an indefinite number of arguments as an array. In simple terms when you don't know how many parameters a function is going to get, we should use rest. Rest helps to create an array of all the arguments that were passed to the function. Syntax to use a rest parameter is simple.
  1. let someMethod = function(...restParam){}    
  2. someMethod(1,2,3,4,5,6);   
In above program I sent 6 parameters which will now be added to restParam array. Rest is different from arguments object which we used to do before ES6. Arguments object is different from rest parameter in a way that rest is true array, that means all the operations which we can do on any normal array, can be performed on rest array too, whereas arguments array was not the true form of array.

Now let's see the traditional way of doing things,
  1. var someMethod = function(name)  
  2. {  
  3.     var result = 0;  
  4.     console.log("Name is: " + name);  
  5.     console.log("Sum of all other parameters are: ");  
  6.   
  7.     for (var i = 1; i < arguments.length; i++)   
  8.     {  
  9.         result += arguments[i];  
  10.     }  
  11.     console.log(result);  
  12. };  
  13. someMethod("Sam", 20, 30, 40, 50, 60);  
In above program I am using arguments object to loop over all the the parameters that were passed to function. This will work, but arguments object is not a true type of array so some of the operations that an array can perform might not be available for arguments array. So, use Rest parameter.
  1. let someMethod = function(name, ...restParameter)   
  2. {  
  3.     let result = 0;  
  4.     console.log("Name is: " + name);  
  5.     console.log("Sum of all other parameters are: ");  
  6.     restParameter.forEach(function(n)   
  7.     {  
  8.         result += n;  
  9.     });  
  10.     console.log(n);  
  11. }  
  12. someMethod("Sam", 20, 30, 40, 50, 60);  
This will generate the same result, but this time instead of using arguments, I am using rest parameter which now contains forEach feature as it is a true array whereas arguments object does not contain any forEach feature.
 
So that's all folks for today. Hit me in comments with suggestions or questions.