JavaScript and ES6 for modern features and syntax


ECMAScript 6 (ES6) is the sixth major version of the ECMAScript language specification, the standard for modern JavaScript. ES6 introduced many new features and syntax improvements that do writing and maintaining JavaScript code easier. Some of the most notable features and syntax improvements are:

  • let and const for variable declarations:


      let x = 5; // declares a variable that can be reassigned
      x = 10;
      console.log(x); // 10

      const y = 7; // declares a constant that cannot be reassigned
      y = 8; // throws an error
      console.log(y);



let and const provide more control over variable scope, let allows to reassign of the variable while const is a constant variable and cannot be reassigned

  • Arrow functions:

      // Old way
      let multiply = function (x, y) {
        return x * y;
      };

      // New way (ES6)
      let multiply = (x, y) => {
        return x * y;
      };

      //or

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


Arrow functions are a shorthand for anonymous functions and also change the way this keyword behaves.

  • Template literals:

      let name = "John";
      console.log(`Hello, ${name}!`); // "Hello, John!"


Template literals make it easier to create strings with embedded expressions. They are enclosed by backticks (`) instead of single or double quotes.

  • Destructuring:

      let arr = [1, 2, 3];
      let [x, y, z] = arr;
      console.log(x, y, z); // 1, 2, 3

      let obj = { a: 1, b: 2, c: 3 };
      let { a, b, c } = obj;
      console.log(a, b, c); // 1, 2, 3


Destructuring allows you to extract values from arrays or objects and assign them to variables.

  • Classes:

      class Person {
        constructor(name) {
          this.name = name;
        }
        sayHello() {
          console.log(`Hello, my name is ${this.name}`);
        }
      }

      let john = new Person("John");
      john.sayHello(); // "Hello, my name is John"

Classes provide a syntax for creating objects with inheritance and encapsulation.

  • Modules:

      // math.js
      export function add(x, y) {
        return x + y;
      }
      export function subtract(x, y) {
        return x - y;
      }

      // main.js
      import { add, subtract } from "./math.js";
      console.log(add(5, 3)); // 8
      console.log(subtract(5, 3)); // 2

Modules provide a way to organize and reuse code.

Default function parameters:

      function greet(name = "John") {
        console.log(`Hello, ${name}!`);
      }

      greet(); // "Hello, John!"
      greet("Mary"); // "Hello, Mary!"

Default function parameters allow you to specify a default value for a function parameter in case it is not provided when the function is called.


  • Spread operator:

      let arr1 = [1, 2, 3];
      let arr2 = [4, 5, 6];
      let arr3 = [...arr1, ...arr2];
      console.log(arr3); // [1, 2, 3, 4, 5, 6]

      let obj1 = { a: 1, b: 2 };
      let obj2 = { c: 3, d: 4 };
      let obj3 = { ...obj1, ...obj2 };
      console.log(obj3); // {a:1,b:2,c:3,d:4}

The spread operator allows you to spread the elements of an array or object into a new array or object.

  • Enhanced object literals:

      let name = "John";
      let age = 30;

      let obj = { name, age };
      console.log(obj); // { name: "John", age: 30 }

      let obj2 = {
        name,
        age,
        sayHello() {
          console.log(`Hello, my name is ${this.name}`);
        },
      };
      console.log(obj2);


Enhanced object literals allow you to write more concise and expressive object literals by using the property name as the key.

  • Promises:

      let promise = new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve("Data is ready");
        }, 2000);
      });

      promise
        .then((data) => {
          console.log(data);
        })
        .catch((error) => {
          console.log(error);
        });

Promises provide a way to handle asynchronous operations in a more elegant and consistent way.

  • Iterators and Generators:

      function* generator() {
        yield 1;
        yield 2;
        yield 3;
      }

      let iterator = generator();
      console.log(iterator.next()); // { value: 1, done: false }
      console.log(iterator.next()); // { value: 2, done: false }
      console.log(iterator.next()); // { value: 3, done: false }
      console.log(iterator.next()); // { value: undefined, done: true }


Iterators are objects that can be used to traverse through a collection of data, and generators are special functions that return iterators. They can be used to create custom iteration logic and to handle infinite sequences of data. 

  • Maps and Sets:

      let map = new Map();
      map.set("name", "John");
      map.set("age", 30);
      console.log(map.get("name")); // "John"
      console.log(map.size); // 2

      let set = new Set();
      set.add("apple");
      set.add("banana");
      set.add("apple");
      console.log(set.size); // 2
      console.log(set.has("apple")); // true


Maps and Sets are new data structures that allow you to store and retrieve key-value pairs and unique values, respectively. They are useful for cases where you need to keep track of unique values or where you need fast lookups.

  • Symbol:

      let sym = Symbol("description");
      console.log(sym.toString()); // "Symbol(description)"
      console.log(typeof sym); // "symbol"

      let obj = {
        [sym]: "hello",
      };
      console.log(obj); // { Symbol(description): "hello" }
      console.log(obj[sym]); // "hello"


Symbols are a new primitive type that can be used to create unique and private properties on objects. They are useful when you need to create properties that should not be enumerable or that should not be overwritten by other code.

  • Async/Await:

      async function getData() {
        try {
          let response = await fetch("https://api.example.com");
          let data = await response.json();
          console.log(data);
        } catch (error) {
          console.log(error);
        }
      }

      getData();

Async/await is a way to write asynchronous code that looks and behaves like synchronous code. It allows you to use the await keyword to wait for a promise to resolve or reject, and it allows you to use the try and catch keywords to handle errors.

  • Rest and spread operator in function parameter:

      function sum(...nums) {
        return nums.reduce((total, num) => total + num, 0);
      }
      console.log(sum(1, 2, 3, 4)); // 10


The rest operator allows you to represent an indefinite number of arguments as an array, and the spread operator allows you to spread the elements of an array into individual arguments. This feature allows you to write more flexible and reusable functions.

  • Array and Object destructuring

      let [first, second] = ["apple", "banana"];
      console.log(first); // "apple"
      console.log(second); // "banana"

      let { name, age } = { name: "John", age: 30 };
      console.log(name); // "John"
      console.log(age); // 30

Destructuring allows you to extract values from arrays or objects and assign them to variables. It makes it easy to extract and use multiple values from an array or object.

Object.assign()

      let obj1 = { a: 1, b: 2 };
      let obj2 = { c: 3, d: 4 };
      let obj3 = Object.assign({}, obj1, obj2);
      console.log(obj3); // { a: 1, b: 2, c: 3, d: 4 }

Object.assign() allows you to merge multiple objects into a single object. It is a simple way to combine the properties of multiple objects into a new object.

  • for...of loop

      let arr = [1, 2, 3];
      for (let num of arr) {
        console.log(num);
      }

The for...of loop allows you to iterate through the elements of an array, map, set, or any other object that implements the iterator protocol. It's a more concise and readable way to iterate through a collection of data.

  • Array.find() and Array.findIndex()

      let arr = [1, 2, 3, 4, 5];
      let num = arr.find((x) => x > 3);
      console.log(num); // 4
      let index = arr.findIndex((x) => x > 3);
      console.log(index); // 3

Array.find() returns the first element in an array that satisfies a given condition, and Array.findIndex() returns the index of the first element in an array that satisfies a given condition. These methods are useful for finding a specific element in an array.

These are just a few examples of the many new features and syntax improvements that ES6 introduced. By using these features, you can write more expressive and maintainable code that is easier to understand and debug. As always, it's important to use a tool like Babel to transpile your code to an earlier version of JavaScript that is compatible with older browsers.