A Quick Dive Into ES6
Tags: javascript, beginners, webdev, discuss
Published: 2020-07-06 17:58:46

ECMAScript 2015 or ES2015 is a significant update to JavaScript programming language. It is the first major update to the language since ES5 which was standardized in 2009. Therefore, ES2015 is often called **ES6**.

## What we'll be covering today

1. Const, let and var
1. Default Arguments
1. Arrow Functions
1. Template literals
1. Map, Reduce and Filter
1. Array and Object Destructuring
1. Iterables and Loopings
1. Rest and Spread Operator
1. Object Literals
1. Classes in ES6s
1. Promises
1. Async and Await
1. "new" and "this" keyword

---

### 1. Const, let and var

**1.1 CONST**

- Const defines a constant variable which can't be changed throught the code.
- Declaring a variable with const is similar to let when it comes to Block Scope.

For example

```js
const x = 100;

/* 
    Re-Initializing The Variable.
    This will throw an error, as CONST variable can't be changed 
*/
x = 200;

/*
    Here 'y' variable is defined in a block. 
    It can't be accessed outside the scope of this block.
    
    The output of this block would be : 
    1
*/
{
  const y = 1;
  console.log(y);
}

/*
    Will throw an error, CONST y is undefined
*/
console.log(y);
```

**1.2 LET**

- "let" defines a variable which can be changed anywhere throught the code.
- It can be re-initialised but not re-declared in the same scope.
- It has a block scope.

```js
let x = 100;

/* 
    Re-Initializing The Variable.
    This will update the value of x to 200 
*/
x = 200;

/* 
    Re-Initializing The Variable in different scopes.
*/

{
  let x = 200;
}
/*  
Will display 100 as output
*/
console.log(x);
```

**1.3 Var**

- Var keyword is an old method for declaring variables in javascript.
- Value of variables declared with var can be changed at any point, during runtime.
- Var has only a global scope.
- MDN recommends to **not to use** `var` keyword after release of `let` and `const` in ES6.

```js
var x = 10;

for (var i = 0; i < 5; i++) {
  var x = 20;
  console.log(x); //Returns 20
}

console.log(x); // Returns 20
```

---

### 2. Default Arguments

Default argument or default parameter allows you to set a default value for your function parameter/argument if **no value** is passed for the same.

**Default Argument with ES5**

```js
function product(x, y) {
  return x * y;
}
/*
    Let's just call the function without passing any argument
    Output would be : NaN
*/
product();
```

**Handling Default Argument with ES5**

```js
function product(x, y) {
  const x = typeof x !== "undefined" ? x : 1;
  const y = typeof y !== "undefined" ? y : 1;
  return x * y;
}
/*
    Since we're handling 
*/
product();
```

In a case when no parameter is passed, we have to explicitly handle the error by setting default values of a & b. This doesn't look like a good way of handling default arguments.

**Handling Default Argument with ES6**

```js
function add(a = 5, b = 10) {
  return a + b;
}

add(); // a=5, b=10, sum = 15;

add(2, 3); // a=2, b=3, sum = 5;

add(4); // a=4, b=10, sum=14 ;
```

Default value of A and B will be only used when no parameter is passed.

---

### 3. Arrow Functions

An arrow function is a syntactically compact alternative to a regular function expression without its own binding to `this`, `super`,

**Regular Functions (ES5)**

```js
function multiply(x, y) {
  return x * y;
}

multiply(10, 4);
```

**Arrow Functions (ES6)**

```js
// Example 1
const multiply = (x, y) => {
  return x * y;
};

multiply(10, 4);
```

---

### 4. Template Literals

Template literals can contain placeholders. These are indicated by the dollar sign and curly braces. The expressions in the placeholders and the text between the backticks (``) get passed to a function. They are used to concatenate the parts into a single string.

Let's see an example on formatting strings in ES5.

```js
    # STRING FORMATTING (WITHOUT ES6)

    function welcome(name){
    	const greetings = 'Hello, ' + name + ' What''s up?';
    	return greetings;
    }

    greet('Ishan');
/*
    Will display output as :
    Hello, Ishan What's up?
*/
```

```js
    # STRING FORMATTING (WITH ES6)

    function welcome(name){
    	const greetings = `Hello, ${name} What's up?`;
    	return greetings;
    }

    greet('Ishan');

/*
    Will display output as :
    Hello, Ishan What's up?
*/

```

You might be able to clearly reciprocate the main benefits of the latter approach.

**RECAP**

- Template Literals are enclosed by back tick(``) instead of single or double quote.
- Placeholders can be inserted between template literals. These are indicated by the dollar sign and curly braces.

---

### 5. Map, Reduce and Filter

Map, reduce, and filter are all array methods which were introduced in ES6. Each one will iterate over an array and perform a transformation or computation. Each will return a new array based on the result of the function.

**Map Method**

The `map()` method is used for creating a new array from an existing one, while passing each element of the array to a function.

For example: Let's say we have a people array that contains multiple persons as object. But, we just need the age of each person.

How can we do that? Here's one

```js
const people = [
  { name: "Ishan", age: 19, profession: "Developer" },
  { name: "Rohit", age: 20, profession: "Student" },
  { name: "Bhavesh", age: 18, profession: "Enterprenuer" },
];

const ages = people.map((person) => person.username);

console.log(ages); // [ 19, 20, 18 ]
```

**Filter Method**

Filter method take a function parameter which applies on each array element, then whichever element satisfies the parameter condition returns in the new array.

For example: Let's consider that in the above people example, I only want to filter those users, who have an age of greater than 18 years.

```js
const people = [
  { name: "Ishan", age: 19, profession: "Developer" },
  { name: "Rohit", age: 20, profession: "Student" },
  { name: "Bhavesh", age: 18, profession: "Enterprenuer" },
];

const aboveEighteen = people.filter((person) => person.age > 18);

console.log(aboveEighteen);
/* [{ name: "Ishan", age: 19, profession: "Developer" },
    { name: "Rohit", age: 20, profession: "Student" } ] */
```

**Reduce Method**

The reduce() method reduces an array of values down to just one value. To get the output value, it runs a reducer function on each element of the array.

For example : Let's say we just want to find the sum of all numbers in an array

```js
const numbers = [1, 2, 3, 4, 5, 6, 7];

// Here prevSum will contain the total sum, upto the previous iterated number.
const sum = numbers.reduce(function (prevSum, num) {
  return prevSum + num;
}, 0);
// Here '0' indicates the initial value of sum, before reducer function is exectued.

console.log(sum); // 28
```

---

### 6. Array and Object Destructuring

Destructuring in JavaScript is a simplified method of extracting multiple properties from an array by taking the structure and deconstructing it down into its own constituent parts. It helps in improving the readability and performance of our code.

**Destructuring in ES5**

```js

//  Object Destructuring
  var person = {
  	name : 'Ishan',
    age : 19',
    profession : 'Developer'
  }

  const name = person.name; // Deepak
  const age = person.age; // dipakkr
  const profession = person.profession // 12345

// Array Destructuring

  const days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday","Sunday"];

  const day1 = days[0];
  const day2 = days[1];
  const day3 = days[2];
```

**Destructuring in ES6**

```js
//  Object Destructuring
  var person = {
  	name : 'Ishan',
    age : 19',
    profession : 'Developer'
  }

  const { name, age, profession } = person;

  console.log(name);
  console.log(age);
  console.log(profession);

// Array Destructing

  const days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday","Sunday"];

  const [day1, day2, day3] = days;

  console.log(day1); // Monday
  console.log(day2); // Tuesday
  console.log(day3); // Wednesday
```

---

### 7. Iterables and Iterators

ES6 introduced a new way to interact with JavaScript data structures — iteration. Here is the list of interable data types in JavaScript.

| Iterable | Description                                                             |
| :------- | :---------------------------------------------------------------------- |
| Array    | We can access each individual element by iterating over an array.       |
| Map      | We can iterate over the key-value pair in a list/array.                 |
| Strings  | Strings are both iterable & array like, so we can access each character |
| Sets     | Collections of values that we can iterate through elements              |

Please note that plain objects are not iterable.

`for...of` is a new feature in ES6 that can be helpful in accessing the interables element more easily. The **_for...of_** statement simply creates a loop iterating over iterable objects. For example,

**Iterating using `for...of`**

```js
const array = [2, 4, 6, 8, 10, 12, 14, 16, 18, 20];

for (var item of array) {
  console.log(item);
}
```

**Iterating without using `for...of`**

```js
const array = [2, 4, 6, 8, 10, 12, 14, 16, 18, 20];

for (var item in array) {
  console.log(array[item]);
}
```

As clearly depicted above, in the latter case we can access interable elements directly with for...of method more easily.

---

### 8. Spread and Rest Operator

Spread and Rest Operators are denoted by `...` three dots. These three dots can either be used as `Rest Parameter` or `Spread Operator`.

**Rest Parameter**  
It simply collects all the remaning arguments into an array and pass them one by one. Hence, allowing a function to be called with any number of arguments, no matter how it is defined.

**Without Using Rest Parameter**

```js
// Function to print sum of numbers.

function addition() {
  var sum = 0;
  for (var i = 0; i < arguments.length; i++) {
    sum = sum + arguments[i];
  }
  return sum;
}

console.log(addition(1, 2, 3, 4, 5, 6, 7, 8, 9)); // 45
```

Here `arguments` is a special array-like object that contains all arguments by their index.

**Using Rest Paramter**

```js
function addition(...numbers) {
  let sum = 0;
  for (let i of numbers) {
    sum += i;
  }
  return sum;
}

console.log(addition(1, 2, 3, 4, 5, 6, 7, 8, 9)); // 45
```

**Spread Operator**

- Using the spread operator, we can expand array/object/string into a single list or other element.
- Spread operator is exactly the reverse of Rest operator, instead of collecting arguments into an array, it expands an array's elements.

For example

```js
/*
  Let's say we want to find the maximum number in two arrays using the
  inbuilt Math.max() function

  Note that Math.max() function expects a list of numeric arguments, not a single array.
*/

let arr1 = [1, -2, 3, 4];
let arr2 = [8, 3, -8, 1];

alert(Math.max(...arr1, ...arr2)); // 8
```

---

### 9. **Object Literals**

Object literals are used to create an object in javascript.

- Object can be initialised by directly using the variable name. See Example 1 below.
- Object's method in ES5 require `function` statement. This is no longer required in ES6, you can directly return statement. See Example 2 below.
- Object literals key in ES6 can be dynamic. Any Express can be used to create a key.

Let's see object literals in action, through an example.

**Object Literals with ES6**

```js
const username = "ishandeveloper";
const name = "Ishan";
const password = "SecretNuclearLaunchCode";
const githubID = "https://github.com/ishandeveloper";

const person = {
  username,
  name,
  password,
  githubID,
};

console.log(person.username);
console.log(person.githubID);
```

### 10. **Classes in ES6**

Classes support prototype-based inheritance, constructors, super calls, instance and static methods

There are two ways to define classes in JavaScript.

1. Class Declaration
2. Class Expression

**Class Declaration**

In order to define class using-declaration method you need to use `class` keyword followed by className. The class name must start with Capital letter.

```js
class Rectangle {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
}
```

**Class Expression**

Class expression is another way to define a class. Class expressions can be named or unnamed. The name given to a named class expression is local to the class's body.

```js
let Rectangle = class {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
};

console.log(Rectangle.name);
```

### 11. Promises

---

For supporting asynchronous programming, JavaScript uses a callback. However, the callback implementation has a major problem which is called as `Callback hell.` Promises come to rescue to solve the problem of callback hell.

**Promises** are a pattern that greatly simplifies asynchronous programming by making the code look synchronous and avoid problems associated with callbacks.

A Promise has three states.

- **pending**: Initial state, neither fulfilled nor rejected.
- **fulfilled**: It means that the operation completed successfully.
- **rejected**: It means that the operation failed.

```js
let promise = new Promise(function (resolve, reject) {
  setTimeout(() => resolve("Success ! "), 2000);
});

promise
  .then(function (result) {
    console.log(result);
  })
  .catch(function (error) {
    console.log(error);
  });

/*
  Result
  Success !
*/
```

> DISCLAIMER : Some of the examples and explanations above are inspired from different sources, and rephrased to some extent in my own words, that help me understand the concepts better, all the credit belongs to the respective authors.

Originally published on [my personal blog](https://blog.ishandeveloper.com/es6-quickdive).