JavaScript ES6 (ECMAScript 2015)

ES6 introduces us to many great features like:

  1. Arrow functions
  2. Block level scope (let, const)
  3. Class
  4. Destructuring
  5. Promises
  6. Default parameters
  7. Rest operator /Spread operator
  8. Template literals
  9. Import & Export

◉ Arrow function

Benefits of arrow function:-

  1. They help in writing concise JavaScript functions.
  2. They have implicit returns, which allows us to write one-liner functions.
  3. They do not rebind this, which is very useful for click handlers.

Syntax:-

// No parameters
() => { statements }
// single parameter
(param) => { statements } OR param => { statements }
// multiple parameters
(param1,param2,....paramN) => { statements }
// Returning objects
// enclose objects by parenthesis so they can be treated as objects
(param1,param2) => ( { id: 1 , key: value });

Note that it’s important, If you use the block syntax in arrow function, you need to use the return keyword, see the following:

let addition = (x, y) => { return x + y; };

If you use typeof operator, it returns function. See the following

let addition = (x, y) => { return x + y; };
console.log(typeof addition); // function

The following expression:

=> expression

is similar to the following expression:

=> { return expression; }

Multiline arrow Function

If you want to write a multiline in arrow functions. You can do it, but it does not allow use a line break between the parameter and arrow ( =>).

For example, the following code produces a SyntaxError:

let multiply = (x,y) 
=> x * y;

However, the following code works absolutely fine:

let multiply = (x,y) => 
x * y;

Want to break the code line from multiline arrow function, shown in the following example:

let multiply = (
x,
y
) =>
x * y;

Also, you can use Arrow function with map, filter, and reduce built-in functions.

Lexical “this”

So in the past you would have used statements like —

.bind(this)
var self = this;

This is known as Lexical Scoping.Earlier, every new function defined its own this value. This proved to be less than ideal for an object-oriented style of programming.

An arrow function does not newly define its own this when it's being executed.The value of this is always inherited from the enclosing scope.

// ES5
function Counter(){
this.seconds = 0;
window.setInterval(function() {
this.seconds++;
}.bind(this), 1000);
}
//ES6
function Counter(){
this.seconds =0;
window.setInterval( () => this.seconds++,1000 );
}

Most people are aware of this feature of ES6 but very few people are aware of the fact that ES6 arrow functions don’t have their own arguments either.

const funct = () => {
console.log(arguments); // This will throw reference error
}
// undefined

Now with ES6, it is NOT possible to get an indefinite amount of arguments inside an array.

When to Avoid arrow functions?? ( You have been warned! )

After learning about Arrow Functions you might be tempted to replace all your ES5 functions, but before you do that, it’s important to understand Arrow functions cannot be used as

Constructors

var Person= (param) => {
this.name = param;
}
var Boy = new Person('Ram');
// Throws error that Person is not a constructor
  • Callback functions with Dynamic Context

It is very common to attach event Listeners to DOM elements like button clicks. An event triggers the handler function with this as the target element.

var button = document.getElementById('myButton');  
button.addEventListener('click', () => {
console.log(this === window); // true and this != button
this.innerHTML = 'Clicked button';
});
  • With new Keyword
var func = () => { console.log("Hello"); };var func1 = new func();
// Uncaught TypeError: func is not a constructor

Arrow functions don’t work as constructors and don’t have [[Construct]] internal method.

So in such cases, you should use function().

◉ Block level scoping (const & let)

const

const is a new keyword in ES6 for declaring variables. const is more powerful than var. Once used, the variable can’t be reassigned. In other words, it’s an immutable variable except when it used with objects.

This is really useful for targeting the selectors. For example, when we have a single button that fires an event, or when you want to select an HTML element in JavaScript, use const instead of var. This is because var is ‘hoisted’. It’s always preferable to use const when don’t want to reassign the variable .

let

let can be reassigned and take new value. It creates a mutable variable.

let is the same as const in that both are blocked-scope. It means that the variable is only available within its scope.

Lets see in example

Edit : Immutable is NOT the right word to use for const. We can alter the values of reference variables like array and objects, but we can’t point to a new array or object if declared using const.

const numbers = [1,2,3]; 
numbers.push(4); //is fine./* But we can’t point to new array */
numbers = [1,2,3,4];//ERROR. We can't point to new array address.

◉ Template Literals

Template literals or template strings are pretty cool. We don’t have to use the plus (+) operator to concatenate strings, or when we want to use a variable inside a string.

The old syntax:

With new ES6 syntax:

Default parameter

So, when you forget to write the parameter, it won’t return an undefined error because the parameter is already defined in the default. So when you run your function with a missed parameter, it will take the value of the default parameter t, and it will not return undefined!

◉ Destructuring

It helps to cleanly extract the properties of an object, assign values from an array or assign properties from an object to variables.

Why ?

Before ES6 was introduced, there was no mechanism to extract all data at once. However, ES6 Destructuring allows

  • to extract multiple properties in a single statement,
  • can access properties from nested objects, and
  • also assign default values to properties if it does not exist.

Swapping Variables

Another useful feature of array destructuring is swapping variables. Previously, creating a temporary variable to store a copy of one of the swapped values was the way to switch the order of two values in the array they are being assigned to. Now, two variables can easily be swapped in a single destructuring expression like this:

let color1 = "red";
let color2 = "blue";
[ color1, color2 ] = [ color2, color1 ];
console.log(color1); // "blue"
console.log(color2); // "red"

Destructuring with Functions

We can also extract the array values returned from a function execution to be able to access its elements easily. Here is a quick example:

Destructuring an array returned from a function

This example shows how the returned array of three colors from the function colors() is destructured.

The order in which we declare variables for destructuring is important in Arrays but not so much in Objects. In objects, the Destructuring is guided mapped by keys (unlike not by sequence as in Arrays).

Moreover, array destructuring is also very popular to assign default values to variables, swap values among variables, etc.

The old syntax:

With ES6 syntax:

With ES5, we have to assign each value to each variable. With ES6, we just put our values within curly brackets to get any property of the object.

Note: if you assign a variable that is not identical to the name of property, it will return undefined. For example, if the name of the property is name and we assign it to a username variable, it will return undefined.

We always have to name the variable the same as the name of the property. But in case we want to rename the variable, we can use the colon : instead.

For the array, we use the same syntax as the object. We have just to replace the curly brackets with square brackets.

◉ Rest operator

The rest syntax (…) uses the same convention as the spread syntax. The difference between the rest and spread syntax is that while spread copies everything, rest is used when we want to retrieve all remaining elements.

const numbers = [1, 3, 2, 6, 8];
const [r1, r2, ...rest] = numbers;
console.log(rest);
console.log(r1);
console.log(r2);
// [2, 6, 8]
// 1
// 3

Spread operator

The spread operator has the same syntax (…) as the rest parameter.

function sum (a, b, c) {
return a + b + c;
};
const numbers = [1, 2, 3];
console.log(sum(...numbers));
// 6
  • The spread operator is used on an iterable (e.g.: arrays, strings) and it helps to expand an iterable into individual elements.
  • The spread operator takes the Array itself and not just the arguments. We can use the Spread parameter to get the values of an Array, instead of using a for loop or any other method.

Why spread Operator?

  • spread syntax for concatenating arrays. Before the spread syntax was introduced, we had to use the array.concat method to combine these arrays.
  • Further, you could also use the spread operator to create copies of objects with the exact same content, but with a different reference.

The object spread operator is conceptually similar to the ES6 array spread operator.

Since one of the core principles of Redux is to never mutate state, you’ll often find yourself using Object.assign() to create copies of objects with new or updated values.

Using Object.assign can quickly make reducers of myApp simple but it is difficult to read.

An alternative approach is to use object spread syntax which lets you spread(…) operator to copy enumerable properties from one object to another object in more brief way.

◉ Classes

Classes were introduced in ECMAScript 2015 to replace the already limited but functional prototype-based inheritance.

To declare a class, we use to class keyword. Classes are the core of object oriented programming (OOP). They make your code more secure and encapsulated.

Syntax

/*Defining Class*/
class ClassName {
constructor(propertyValue){
this.property = propertyValue;
}
functionName(){
// function body
}
}
/* Creating objects from class */
let objName = new ClassName(propertyValue);

we can access the class methods and properties using the new keyword.

class Animal{
constructor(name, sound){
this.name = name;
this.sound = sound;
}

speak(){
console.log(this.name + `${this.sound}`);
}
let dog = new Animal('Sprinkles', 'barks');
dog.speak();

The keywords introduced are: class, constructor

Now before we discuss what these keywords mean and what they do exactly, let’s see how we can create such a ‘class’ using a traditional function.

# creating a "CLASS" using a traditional approachfunction Animal(name, sound){
this.name = name;
this.sound = sound;
}
Animal.prototype.speak = function(){
console.log(this.name + ' ' + this.sound);
}
var dog = new Animal('Sprinkles', 'barks!');
dog.speak();

The above example uses a constructor function and the properties ‘name’ and ‘sound’ are set on the object using the ‘this’ keyword. We set a method on the prototype of the Animal function such that all Animal objects will inherit the ‘speak()’ method. Both examples achieve the same thing. In fact, if you create an object of Animal written in ES6-style and run this

typeof Animal; // function

Yes! it returns ‘function’. Javascript hasn’t even added a new type to the language. The ES6 class is just an elegant way to do the same thing.

Now let’s see what are the differences that we can draw syntactically from the two examples:

In the ES6-Class way,

  • function keyword is not used to declare functions. We don’t need to have the word function for declaring methods.
  • We can’t assign properties as we do in methods. We initialize them using a constructor method.
  • constructor method is a special method which is called on the creation of objects and used to initialize the class instance.
  • this will always point to the current object
  • The function keyword is replaced with the class keyword.
  • There’s a special function named ‘constructor’ where the initialization of the object is done. Hence whatever is present in the body of the traditional function gets shifted to the ‘constructor’ function. This method is called whenever a new object of that ‘class’ is created.
  • The speak() method is a part of the class body and it is considered a ‘member’ of the class.

The static method

You can also call super on static methods as below:

Class example with `static` methods
class Animal{
constructor(name, sound){
this.name = name;
this.sound = sound;
}
speak(){
console.log(this.name + this.sound);
}
static allSpeak(animals){
for(animal of animals){
console.log(animal.name + animal.sound);
}
}
}Animal.allSpeak(animal1, animal2, animal3);

The static keyword allows you to set a method on the ‘class’ itself and not the object. The static method is directly accessed with the class name instead of the object. It throws an error if it’s called with an object.

You may ask what’s the point of classes? It is just an alternative syntax to achieve the same thing, but I beg to differ. The ES6 class offers a ton of benefits.

Benefits of classes

  1. Less code setup — Who doesn’t want to write less code? With ES6 classes the code to write a function is much lesser compared to the traditional method.
  2. Constructor function — it provides a clear function to create objects.
  3. All the logic is contained — You can clearly specify the methods and properties in one place instead of creating one constructor function and defining methods on the prototype one-by-one.

Things to remember about ES6 classes

  1. There’s no magic — The Javascript class must not be confused with the object-oriented features provided by other class-based languages like Java, C++ etc.
  2. The class is just an illusion — Javascript did not add any additional features. It still follows prototypal inheritance under the hood.
  3. The classes require the use of new keyword — Whenever instantiating an object of a class, the new keyword must be used.
  4. One important aspect of classes is, unlike function declarations, classes are hoisted. This means that you cannot create an object before accessing it, otherwise the code will throw a ReferenceError.
  5. There can only be one constructor and a SyntaxError will be thrown if a class embodies more than one constructor. If a class does not have a constructor, a default one will be assigned and used.

The “super” and “extends” keywords

You can create a subclass or a child class using the ‘extends’ keyword. The child class can add its own logic along with the data inherited from the ‘base’ class. Also, if the sub class has a constructor, you will have to call super() first before using the this keyword.

class Animal {
constructor(){
this.name = name;
}
speak(){
console.log(this.name + ' makes a noise.');
}
}
class Dog extends Animal {
constructor(name, sound = 'noise'){
super(name);
this.sound = sound;

speak() {
console.log(this.name + this.sound);
}
}
let dog1 = new Dog('Barnacles');
dog1.speak(); // Barnacles barks

In the above example, the subclass ‘Dog’ overrides the speak() method and defines its own. The ‘super’ keyword is used to call the base class’s constructor function. Remember if the subclass has a constructor then the first line should be the call to super() before doing anything else. If you don’t call super then it will throw an error!

Mix-ins.

A class can have only one single super class, this makes multiple inheritance from tooling classes impossible. This is where mix-ins or abstract sub classes come in. A mix-in provides the functionality for a class to have multiple inheritance

◉ Modules (Import and export)

Modules means dividing our code in different files for reusability and better maintainability. A module can be referred as a single JavaScript file.

Methods, classes, variables declared in one module are private by default. We can’t use them in other modules directly. Scope of variables declared globally also is limited to a single file or module only.

This is a great benefit of Modules as explained below:

If the global variable is declared with same name in two files, the variable is overwritten by later declaration. But this is NOT applicable in ES6, because the scope of globally declared variables is limited to single module or file only. Global variables in different modules are treated as different variables.

Now thinking, then how to access variables of one module in another module. eh..?

If we want to use the variables in different modules, we have to explicitly export variables, methods to make them public.

We use the export keyword before class and variables to make them available for other modules. The import keyword is used to import variables or classes from other modules

Export: export const variableName or export class ClassName{}

Import: import {exportedObject} from ‘filePath’

It is simple! export allows you to export a module to be used in another JavaScript component. We use import to import that module to use it in our component.

In detailComponent.js we are going to export the detail function.

And if we want to use this function in homeComponent.js, we will just use import.

If we want to import more than one module, we just put them within curly brackets.

You can export members one by one, by adding “export” keyword before each member or you can export all the members at the same time as a group.

You can define a default export with the “default” keyword as well.

When importing the exported modules, You have to use “import” keyword. Importing modules’ names should be surrounded by curly braces if it is not a “default exported” member.

Assume the file containing the above (Image )code is app.js. You can import those members as follows.

import {myNumbers,myFunc} , myStr from 'app.js';

The reason why I have not surrounded ‘myStr’ with curly braces is that, it is exported default. When you import a default exported member, you can give any name you need for that member. You can have only one default export per file. It is not necessary to use the exact same method name you used for the default exported member when importing.

Named exports are useful to export several values.

◉ Promises

Promises are a new feature of ES6. It’s a method to write asynchronous code. It can be used when, for example, we want to fetch data from an API, or when we have a function that takes time to be executed. Promises make it easier to solve the problem, so let’s create our first Promise!

If you log your console, it will return a Promise. So, if we want to execute a function after data is fetched, we will use a Promise. The Promise takes two parameters: resolve and reject to handle an expected error.

Note: the fetch function returns a Promise itself!

const url='https://jsonplaceholder.typicode.com/posts';const getData=(url)=>{
return fetch(url);
}
getData(url).
then(data=> data.json()).
then(result=> console.log(result));

Now if you log your console it will return an array of data.

source(s): https://medium.com/free-code-camp/write-less-do-more-with-javascript-es6-5fd4a8e50ee2

6 Great Uses of the Spread Operator

References:

Must Read @ https://medium.com/@rashmishehana_48965/must-know-es6-features-for-react-97ad57468623

Experience with Front-end Technologies and MERN / MEAN Stack. Working on all Major UI Frameworks like React, Angular.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store