Top 10 ES6 Features Every JavaScript Developer Should Know

Top 10 ES6 Features Every JavaScript Developer Should Know

Discover the Revolutionary Features of ECMAScript 6 for Enhanced Web Devlopment

Introduction

If you are a javascript learning aspirant or developer you may across the word of ES6. If you're unfamiliar with it. This is the right place for you, In this blog, I will provide in-depth explanations of ES6 and highlight the key difference between its previous version of ES5.

Let’s start with What is ES6. ES6 is just a release of the sixth version of ECMAScript 6 (ES6) also known as ECMAScript 2015.

In this blog post, we will delve into the world of ES6 syntax, exploring its most notable additions and demonstrating how they can revolutionize your JavaScript development experience. Whether you're a seasoned JavaScript developer or just starting your coding journey, understanding ES6 syntax is crucial for writing cleaner, more expressive, and efficient code.

I'll cover some of the key features brought by ES6, including block-scoped variables, arrow functions, classes, template literals, destructuring assignments, and much more. Through clear explanations and practical examples, I'll show you how these features can simplify your code and make it more readable, maintainable, and concise.

Are you ready to dive into the world of ES6 syntax and take your JavaScript skills to the next level? Let's get started!

Variable and Constant Declarations :

In ES5, the var keyword is used to declare variables in a non-scoped manner, which allows them to be reassigned and hoisted within the module at any time.

Code snippet in ECMAScript 5 (ES5):

Variable Declaration :

var x = 0;

To address this, ES6 introduced two new ways of declaring variables: let and const.While let allows for block-scoped variables, const enables the declaration of variables that cannot be reassigned.

Code snippet in ECMAScript 6 (ES6):

Variable Declaration :

let x = 0

Constant Declaration :

const CONST_IDENTIFIER = 0

Please refer to the table below for a more concise understanding of the differences between var, let, and const.

ScopeReassignmentHoisting
varNon-block scopedAllowedHoisted
letBlock scopedAllowedNot hoisted
constBlock scopedNot allowedNot hoisted

Arrow Function :

In ES5, you need to define functions using function declaration for the expression and include return statements, defining variables and prototypes for objects. Additionally, other objects can Inherit Properties and methods from this Prototype.

Code snippet in ECMAScript 5 (ES5):

var multiply = function(a, b) {
    return a * b;
};

To address these limitations ES6 introduce a feature called Arrow functions. It provides a more concise syntax for writing function expressions by removing the function and return keywords. In ES5, functions are employed to create class constructors and generate objects. However, in Arrow functions, they lack their own this value, prototypes, constructor usability, and should not be utilized as object methods.

Arrow functions are defined using the fat arrow (=>) notation.

Code snippet in ECMAScript 6 (ES6):

const multiply = (a, b) => a * b;

Note :

if there are multiple expressions in the function body, then we need to wrap it with curly braces ("{}"). We also need to use the "return" statement to return the required value.

Template Literals :

In ES5, to concatenate strings with variables, we had to break the strings and add variables using the "+" operator, which could become cumbersome and daunting, especially for longer strings.

Code snippet in ECMAScript 5 (ES5):

var name = "Adam";
var age = 23;
console.log("Hello, my name is " + name + " and I am " + age + " years old.");

ES6 template literals, denoted by backticks (`), allow us to easily insert variables into a string by enclosing them within ${} placeholders and also support multiline strings. This eliminates the need for concatenation or complex string manipulation techniques, making string manipulation tasks more convenient and readable.

Code snippet in ECMAScript 6 (ES6):

const name = 'Adam';
const age = 23;

const message = `Hello, my name is ${name} and I am ${age} years old.`;
console.log(message);

Destructuring (Object Matching):

In ES5 you need to create a distinct variable to access each property in the object and index elements in an array. This results in a lengthier code, especially when dealing with a vast range of properties and indices, as shown in the code snippet below.

Code snippet in ECMAScript 5 (ES5):

var person = {
  firstName: 'Adam',
  lastName: 'Jose',
  age: 23,
  city: 'New York'
};

var firstName = person.firstName;
var lastName = person.lastName;
var age = person.age;
var city = person.city;

console.log(firstName);  // Output: Adam
console.log(lastName);   // Output: Jose
console.log(age);        // Output: 23
console.log(city);       // Output: New York

To overcome these limitations, ES6 introduces destructuring, enabling you to extract values from objects or arrays and assign them to separate variables, resulting in a more concise and readable code.

Code snippet in ECMAScript 6 (ES6):

const person = {
  firstName: 'Adam',
  lastName: 'Jose',
  age: 23,
  city: 'New York'
};

const { firstName, lastName, age, city } = person;

console.log(firstName);  // Output: Adam
console.log(lastName);   // Output: Jose
console.log(age);        // Output: 23
console.log(city);       // Output: New York

Array Iterations :

In ES5 we use the old-school method of for and while loops to iterate over the elements of an array. In this case, the loop will run until an indexing variable reaches the length of the array. at each iteration, elements are accessed using an index like below code snippets.

Code snippet in ECMAScript 5 (ES5):

var numbers = [1, 2, 3, 4];

for (var i = 0; i < numbers.length; i++) {
    console.log(numbers[i]); // Logs each element in the array
}

In ES6 there are a lot of new features introduced for Iteration to make concise and easily expressive way, for example for..of loop directly over the value of iterable object such as an array, string, map and set and so on. it simply replaces the need for indexing and makes it more convenient for array iteration.

Code snippet in ECMAScript 6 (ES6):

const numbers = [1, 2, 3, 4];

for (const number of numbers) {
    console.log(number); // Logs each element in the array
}

Default Parameters:

In ES5, when you wanted to assign a default value to a function parameter, you had to manually check if the value was undefined within the function body and set it to the default value when necessary. This was commonly achieved using conditional statements like the ternary operator.

Code snippet in ECMAScript 5 (ES5):

function multiply(a, b) {
  b = typeof b !== "undefined" ? b : 1;
  return a * b;
}

multiply(5, 2); // 10
multiply(5); // 5

To overcome this limitation, ES6 introduces a new feature called Default Parameters. This allows you to assign default values directly in the function parameter lists, eliminating the need to manually check for undefined within the function body.

Code snippet in ECMAScript 6 (ES6):

function multiply(a, b = 1) {
  return a * b;
}

multiply(5, 2); // 10
multiply(5); // 5
multiply(5, undefined); // 5

Spread Syntax:

In ES5, we rely on methods like concat() and slice() for array concatenation and copying. For passing arguments to functions, we use the apply() method to invoke the function with an array of arguments.

Code snippet in ECMAScript 5 (ES5):

// Concatenating Arrays
var array1 = [1, 2, 3];
var array2 = [4, 5, 6];
var concatenatedArray = array1.concat(array2);
console.log(concatenatedArray);

// Copying Arrays
var originalArray = [1, 2, 3];
var copiedArray = originalArray.slice();
console.log(copiedArray);

// Passing Arguments to Functions
function sum(a, b, c) {
  return a + b + c;
}
var args = [1, 2, 3];
var result = sum.apply(null, args);
console.log(result);

To overcome these limitations, ES6 introduced the spread syntax, denoted by the ellipsis (...). This feature allows for the expansion of iterable objects, such as arrays or objects, into individual elements. With the spread syntax, we can easily concatenate arrays by expanding the elements of both arrays into a new array. Similarly, copying arrays becomes a breeze as we can simply spread the elements of the original array into a new array.

Code snippet in ECMAScript 6 (ES6):

// Concatenating Arrays
const array1 = [1, 2, 3];
const array2 = [4, 5, 6];
const concatenatedArray = [...array1, ...array2];
console.log(concatenatedArray);

// Copying Arrays
const originalArray = [1, 2, 3];
const copiedArray = [...originalArray];
console.log(copiedArray);

// Passing Arguments to Functions
function sum(a, b, c) {
  return a + b + c;
}
const args = [1, 2, 3];
const result = sum(...args);
console.log(result);

Classes/Constructor Functions:

In ES5, there is no default class keyword to create a class. To create classes, you need to define a constructor function that acts as a class constructor. Properties and methods are then added to the class using a prototype.

Code snippet in ECMAScript 5 (ES5):

// Constructor function for the "Person" class
function Person(firstName, lastName) {
  this.firstName = firstName;
  this.lastName = lastName;
}

// Method added to the prototype of "Person" class
Person.prototype.getFullName = function() {
  return this.firstName + ' ' + this.lastName;
};

// Creating an instance of the "Person" class
var adamjose = new Person('Adam', 'Jose');

console.log(adamjose.getFullName()); // Output: Adam Jose

ES6 introduced a more familiar class-based syntax for object-oriented programming in JavaScript, similar to other programming languages. This new syntax simplifies the creation of classes. To create a class in JavaScript, you simply define the class keyword followed by the name of the class.

Code snippet in ECMAScript 6 (ES6):

// Create a Person Class
class Person {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }

// Create a method in Person class
  getFullName() {
    return this.firstName + ' ' + this.lastName;
  }
}

// Creating an instance of the "Person" class
const adamjose = new Person('Adam', 'Jose');

console.log(adamjose.getFullName());  // Output: Adam Jose

Modules - Export/Import:

Both import and export play significant roles in large projects, enabling the sharing of code across different files.

In ES5, there is no direct import and export method to access code from various files. To achieve export behavior, developers often employ revealing module patterns or global variables and export using the module.exports keyword. To import a file, the required keyword is used to access the methods and properties from the exported module.

Export in ES5

// File: mathOperations.js
var add = function(a, b) {
  return a + b;
};

var multiply = function(a, b) {
  return a * b;
};

module.exports = {
  add: add,
  multiply: multiply
};

Import in ES5

// File: main.js
var mathOperations = require('./mathOperations');

var result1 = mathOperations.add(5, 3);
var result2 = mathOperations.multiply(2, 4);

console.log(result1); // Output: 8
console.log(result2); // Output: 8

To overcome this limitation, ES6 introduces the export and import keywords, allowing developers to organize project files and share code across different modules efficiently.

Export in ES6

// File: mathOperations.js
export const add = function(a, b) {
  return a + b;
};

export const multiply = function(a, b) {
  return a * b;
};

Import in ES6

// File: main.js
import { add, multiply } from './mathOperations';

const result1 = add(5, 3);
const result2 = multiply(2, 4);

console.log(result1); // Output: 8
console.log(result2); // Output: 8

Promises/Callbacks:

In ES5, performing asynchronous operations involves using callbacks, which often leads to the notorious Callback hell or pyramid of doom. Callbacks require passing functions as arguments to another function, which are executed later within the outer function. Although this approach is suitable for small tasks and appears neat, it becomes difficult to read and maintain when dealing with highly nested functions due to their inherent behavior.

Code snippet in ECMAScript 5 (ES5):

function fetchData(callback) {
  fetchDataFromServer(function (data) {
    processData(data, function (processedData) {
      saveDataToDatabase(processedData, function (result) {
        callback(result);
      });
    });
  });
}

fetchData(function (result) {
  console.log(result);
});

ES6 introduced Promises, offering a more elegant and structured approach to handle asynchronous operations, effectively avoiding the infamous "callback hell" scenario. Promises utilize the concept of pending, resolve, and reject, enabling a sequential and organized execution of functions one by one.

Code snippet in ECMAScript 6 (ES6):

function fetchData() {
  return new Promise(function (resolve, reject) {
    fetchDataFromServer(function (data) {
      resolve(data);
    });
  });
}

function processData(data) {
  return new Promise(function (resolve, reject) {
    // Process the data here...
    resolve(processedData);
  });
}

function saveDataToDatabase(data) {
  return new Promise(function (resolve, reject) {
    saveDataToDatabase(data, function (result) {
      resolve(result);
    });
  });
}

fetchData()
  .then(processData)
  .then(saveDataToDatabase)
  .then(function (result) {
    console.log(result);
  })
  .catch(function (error) {
    console.error("An error occurred:", error);
  });

Conclusion :

In conclusion, ES6 has not only enriched JavaScript but also revolutionized how we approach modern web development. As developers, let's leverage these powerful features to create a cleaner, more maintainable, and future-proof codebase. So, let's embrace ES6 and unlock the full potential of JavaScript, taking our coding skills to new heights.

Happy coding!