BlogsDope image BlogsDope

JavaScript ES5 vs. ES6

July 14, 2020 JAVASCRIPT 14996

ECMAScript is the scripting language, and it forms the basis of JavaScript. Today, we are going to look at the differences between its two versions, ES5 and ES6. Throughout the article, you will see how ES6 enables us to write a code that is more readable, concise, and efficient. So, without further ado, let’s get started.

ES5 stands for ECMAScript 5. It is also known as ECMAScript 2009. Whereas, ES6 stands for ECMAScript 6 (ECMAScript 2015).

ES6

Arrow Functions


Arrow functions got introduced in ES6. This way of defining methods is concise and more readable. It does not require the keyword function, and sometimes not even return keyword and curly brackets.

Consider the following example that calculates the square of a number.

// in ES5
function square(num) {
  return num * num;
}
// in ES6
var square = (num) => {
  return num * num;
};
// equivalent way ES6
var square = (num) => num * num;

As you can see, how easier it is to write functions using arrow function expressions. The method in line 6 is a more general way of writing arrow functions. In line 8, we have written an equivalent function with omitted parenthesis, curly brackets, and return keyword. In particular, if the function contains a single parameter, then you can ignore the parenthesis. Moreover, if it has only one statement, then you can ignore the curly brackets and the return keyword as well.

Variables: let and const


In ES5, we only have one way of defining variables, i.e., using the keyword var. ES6 introduces two more ways of defining variables, const and let. var uses function scope, i.e., it is accessible in its function. However, let and const use block scope, i.e., they are only defined in their block. Outside that block, they are inaccessible. Variables defined using const are immutable, i.e., their values can't be changed. Let's see.

function test() {
  for (let i = 0; i < 2; i++) {
    var j = i;
    console.log("i: " + i);
    console.log("j: " + j);
  }
  console.log("Outside the for loop block");
  console.log("j: " + j);
  console.log("i: " + i);
}

Output

ES6 vs ES5

Here, the variable “j” has function scope (it is accessible anywhere in the function in which it is defined), and the variable “i” has block scope (accessible only in the for loop). That’s why, when you try to access “i” outside its block, it gives a reference error. If we change the keyword of “i” from let to var, then we will be able to use it.

Consider the following example, in which we try to change the value of a constant.

const a = 4;
console.log(a);
a = 5;
console.log(a);

Output

ES5 vs ES6

Merge Objects


In ES5, the Object.assign() method merge objects. It requires a target object and one or more source objects. It copies the properties from the source object(s) to the target object. ES6 introduced a simpler way of doing that using the spread operator (…). Let’s see.

var target = { name: "xyz", age: 20 };
var source1 = { name: "abc", grade: 12 };
var source2 = { gender: "female" };

//In ES5
updatedTarget = Object.assign(target, source1, source2);
console.log(updatedTarget, target);

Output

ES5 vs ES6

var target = { name: "xyz", age: 20 };
var source1 = { name: "abc", grade: 12 };
var source2 = { gender: "female" };

// In ES6
updatedTarget = { ...target, ...source1, ...source2 };
console.log(updatedTarget, target);

Output

ES4 vs ES6

The difference between the Object.assign() method and the spread operator is that the spread operator does not change the target variable, while the Object.assign() does.

Object Destructuring


Before ES6, we had to extract objects manually, which is time-consuming, and it takes more lines of code as well. ES6 introduced an elegant way of unpacking object properties. It just takes one line of code. Let’s see.

var object = { name: "xyz", age: 20, grade: 12, gender: "female" };

// ES5
var name = object.name;
var age = object.age;
var grade = object.grade;
var gender = object.gender;

// ES6
var { name, age, grade, gender } = object;

Awesome, Right?

Defining objects


var name = "xyz";
var age = 20;
var grade = 12;
var gender = "female";

// ES5
var object1 = { name: name, age: age, grade: grade, gender: gender };
// ES6
var object2 = { name, age, grade, gender };

As you can see, we can use the above shorthand in ES6, when the keys and the variable names are the same.

Module Export


Let’s see how exporting a module in ES6 varies from that of ES5.

var myTestModule = { name: "xyz", age: 20, grade: 12, gender: "female" };

// ES5
module.exports = myTestModule;

// ES6
export default myTestModule;

// ES6
export const name = "xyz";
export const age = 20;

ES6 also allows you to export multiple child modules and variables.

Module Import


Let’s see how we can import a module in ES5 and ES6.

//ES5
var myTestModule = require("./myTestModule");

//ES6
import myTestModule from "./myTestModule";

// ES6 import child modules
import { name, age } from "./myTestModule";

String Interpolation


We often join strings using the concatenation operator. However, this approach becomes a bit inconvenient when you have to place variables within strings, i.e., you have to open and close strings at different places. ES6 introduced a new feature known as Template Literal (`) that allows us to perform string interpolation more conveniently. Let’s see.

var name = "abc";
var age = 20;
var grade = 12;

// ES5
var str = name + " is " + age + " years old and studying in grade " + grade;

// ES6
var str = `${name} is ${age} years old and studying in grade ${grade}`;

Callbacks and Promises


Consider a simple example that checks whether the user has access or not. The global variable access is true if the user has access. Otherwise, it is false. The test() function takes two callback functions, callback() and errorCallback(), as arguments. If the user has access, then the callback() method is called, and if the user doesn’t, then the errorCallback() method is called. Both of them display a message depending upon the condition. Let’s see.

var access = true;
function callback(message) {
  console.log("Success!" + message);
}

function errorCallback(message) {
  console.log("Failed!" + message);
}

function test(callback, errorCallback) {
  if (access) {
    callback("You do have access");
  } else {
    errorCallback("You don't have access");
  }
}

Let’s now do the same example using ES6 Promises.

var access = true;
function test1() {
  return new Promise((resolve, reject) => {
    if (access) {
      resolve("You do have access");
    } else {
      reject("You don't have access");
    }
  });
}

test1()
  .then((message) => console.log("Success!" + message))
  .catch((message) => console.log("Failed!" + message));

The test1() function returns a Promise object. The Promise object takes a function that has two parameters, resolve and reject. If the value of access is true, resolve() gets called. If it is false, reject() gets called. Anything inside .then() is going to run for resolve(), and anything inside .catch() is going to run for reject(). Therefore, .then() is going to be called if our Promise resolves successfully, and catch() is going to be called, if our Promise fails. As you can see in the above examples, Promises are a cleaner way of doing callbacks.

That’s it. :)


Liked the post?
A computer science student having interest in web development. Well versed in Object Oriented Concepts, and its implementation in various projects. Strong grasp of various data structures and algorithms. Excellent problem solving skills.
Editor's Picks
0 COMMENT

Please login to view or add comment(s).