DEV Community

Cover image for A Quick Dive Into ES6
Ishan Sharma
Ishan Sharma

Posted on • Updated on • Originally published at blog.ishandeveloper.com

A Quick Dive Into ES6

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
  2. Default Arguments
  3. Arrow Functions
  4. Template literals
  5. Map, Reduce and Filter
  6. Array and Object Destructuring
  7. Iterables and Loopings
  8. Rest and Spread Operator
  9. Object Literals
  10. Classes in ES6s
  11. Promises
  12. Async and Await
  13. "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

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);
Enter fullscreen mode Exit fullscreen mode

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.
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);
Enter fullscreen mode Exit fullscreen mode

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.
var x = 10;

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

console.log(x); // Returns 20
Enter fullscreen mode Exit fullscreen mode

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

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

Handling Default Argument with ES5

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();
Enter fullscreen mode Exit fullscreen mode

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

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 ;
Enter fullscreen mode Exit fullscreen mode

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)

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

multiply(10, 4);
Enter fullscreen mode Exit fullscreen mode

Arrow Functions (ES6)

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

multiply(10, 4);
Enter fullscreen mode Exit fullscreen mode

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');
Enter fullscreen mode Exit fullscreen mode

/*
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');
Enter fullscreen mode Exit fullscreen mode

/*
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

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 ]
Enter fullscreen mode Exit fullscreen mode

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.

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" } ] */
Enter fullscreen mode Exit fullscreen mode

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

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
Enter fullscreen mode Exit fullscreen mode

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


//  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];
Enter fullscreen mode Exit fullscreen mode

Destructuring in ES6

//  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
Enter fullscreen mode Exit fullscreen mode

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

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

for (var item of array) {
  console.log(item);
}
Enter fullscreen mode Exit fullscreen mode

Iterating without using for...of

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

for (var item in array) {
  console.log(array[item]);
}
Enter fullscreen mode Exit fullscreen mode

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

// 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
Enter fullscreen mode Exit fullscreen mode

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

Using Rest Paramter

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
Enter fullscreen mode Exit fullscreen mode

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

/*
  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
Enter fullscreen mode Exit fullscreen mode

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

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);
Enter fullscreen mode Exit fullscreen mode

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.

class Rectangle {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
}
Enter fullscreen mode Exit fullscreen mode

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.

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

console.log(Rectangle.name);
Enter fullscreen mode Exit fullscreen mode

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.
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 !
*/
Enter fullscreen mode Exit fullscreen mode

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.

Top comments (1)

Collapse
 
lexlohr profile image
Alex Lohr

I think you didn't do the Iterators/Iterables/Generators justice, missing out on function* and yield, the difference between async and sync iterators (the former can yield promises), the simple patterns behind the semantic sugar, why Symbol was required to create them and why they are a prerequisite for rxjs and (to come later) native observables.