DEV Community

Mukesh
Mukesh

Posted on

JavaScript ES6+ Features: A Complete Overview

Introduction

JavaScript is constantly evolving, and keeping up with the latest features is crucial for modern web development. Since ES6, JavaScript has introduced new features that make coding more efficient.

Understanding and utilizing the latest JavaScript features can greatly enhance your productivity and code quality, making your applications more robust and maintainable.

In this blog, will provide overview of the key features introduced in ES6 and beyond, including let and const, arrow functions and more.

Key Features Introduced in ES6+

1. let and const

JavaScript introduced two new ways to declare variables let and const. These provide better scoping and more control over how variables are used in your code compared to the traditional var.

let

let is used to declare variables that can be reassigned. Unlike var, let has block scope, meaning it is only accessible within the block (curly braces {}) where it is defined.

Example

if (true) {
    let x = 10;
    console.log(x); // Output: 10
}
console.log(x); // Error: x is not defined

Enter fullscreen mode Exit fullscreen mode
  • The if statement checks if the condition true is met (which it always is in this case).
  • When the condition is true, the code block { ... } executes.
  • let x = 10; declares a variable x with block scope (scoped to the nearest curly braces { ... }).
  • x is assigned the value 10.
  • console.log(x); outputs the value of x, which is 10, to the console.
  • The output displayed is 10.
  • console.log(x); attempts to output the value of x to the console.
  • However, x is not accessible outside the block where it was defined (if block).
  • JavaScript throws an error: ReferenceError: x is not defined.
  • This error occurs because let variables are block-scoped and exist only within the block (curly braces) where they are defined.

const

const is used to declare variables that should not be reassigned. Like let, const has block scope. Once a variable is assigned a value using const, it cannot be changed.

const y = 20;
console.log(y); // Output: 20
y = 30; // Error: Assignment to constant variable.

Enter fullscreen mode Exit fullscreen mode
  • const declares a constant variable named y.
  • Constants (const) are variables that cannot be reassigned once their value is set.
  • y is initialized with the value 20.
  • console.log(y); outputs the value of y, which is 20, to the console.
  • The output displayed is 20.
  • Attempts to reassign the value of y to 30.
  • However, constants (const) in JavaScript cannot be reassigned after their initial assignment.
  • JavaScript throws an error: TypeError: Assignment to constant variable.
  • This error occurs because y is declared as a constant (const), and you cannot change its value once it's set.

2. Arrow Functions

Description:
Arrow functions provide a concise syntax for writing function expressions. They do not have their own this context, making them particularly useful for callbacks.

Example

// Traditional function expression
var add = function(a, b) {
    return a + b;
};

// Arrow function expression
const add = (a, b) => a + b;

Enter fullscreen mode Exit fullscreen mode
  • var add declares a variable named add. This variable will store a function.
  • The function(a, b) part creates an anonymous function (a function without a name) that takes two parameters, a and b.
  • Inside the curly braces {}, the function body contains a single statement: return a + b;. This means the function will add the two parameters a and b and return the result.
  • The function is assigned to the variable add. Now, add can be used to call the function and perform the addition.
  • When add(2, 3) is called, the function adds 2 and 3 and returns 5.
  • const add declares a constant variable named add. This means the variable add cannot be reassigned to a different value or function.
  • The (a, b) => a + b part is an arrow function. It is a shorter and more concise way to write a function.
  • (a, b) lists the parameters of the function, just like in the traditional function expression.
  • The a + b part is the body of the function. Since there are no curly braces {}, this function has an implicit return, meaning it automatically returns the result of a + b.
  • When add(2, 3) is called, the arrow function adds 2 and 3 and returns 5.

3. Template Literals

Template literals let us create strings that can span multiple lines and include variables easily. Use template literals for embedding variables and expressions in strings.

Example:

const name = 'John';
const greeting = `Hello, ${name}!`;
console.log(greeting); // Hello, John!

Enter fullscreen mode Exit fullscreen mode
  • const declares a constant variable named name.
  • 'John' is assigned as the value of name.
  • Constants const are variables that cannot be reassigned once their value is set.
  • Template literals (enclosed in backticks) allow embedding expressions inside strings.
  • ${name} within ${} is an expression that gets replaced with the value of the name variable.
  • ${name} evaluates to 'John', so greeting becomes 'Hello, John!'.
  • console.log() outputs the value of greeting to the console.
  • The output displayed in the console is Hello, John!.

4. Destructuring Assignment

Destructuring allows you to unpack values from arrays or properties from objects into distinct variables. Use destructuring to simplify the extraction of values from arrays and objects.

Example:

const user = { name: 'John', age: 30 };
const { name, age } = user;
console.log(name); // John
console.log(age); // 30
Enter fullscreen mode Exit fullscreen mode
  • const declares a constant variable named user.
  • user is an object with two properties: name with value 'John' and age with value 30.
  • Object destructuring allows you to extract specific properties from an object into variables with the same names.
  • { name, age } on the left-hand side of = declares two new variables (name and age).
  • These variables are assigned the values of user.name and user.age, respectively.
  • console.log(name); outputs the value of the variable name to the console.
  • The output displayed in the console is John.
  • console.log(age); outputs the value of the variable age to the console.
  • The output displayed in the console is 30.

5. Default Parameters

Default parameters allow you to set default values for function parameters if no value or undefined is passed. Use default parameters to ensure functions have default values.

Example:

function greet(name = 'Guest') {
    console.log(`Hello, ${name}!`);
}
greet(); // Hello, Guest!

Enter fullscreen mode Exit fullscreen mode
  • function greet(...) declares a function named greet.
  • name = 'Guest' is a parameter with a default value of 'Guest'. This means if no argument is passed to greet(), name will default to 'Guest'.
  • Template literals (enclosed in backticks `) allow embedding expressions inside strings.
  • ${name} within ${} is an expression that gets replaced with the value of the name parameter passed to the function.
  • If no name parameter is provided, it defaults to 'Guest'.
  • greet() calls the greet function without passing any arguments.
  • Since no argument is passed, name defaults to 'Guest'.
  • The function then logs 'Hello, Guest!' to the console.

6. Rest and Spread Operators

The rest operator (...) allows you to represent an indefinite number of arguments as an array. The spread operator (...) allows an iterable to be expanded in places where zero or more arguments or elements are expected. Use rest operator in function parameters to handle various arguments. Use spread operator to expand arrays and objects.

Example:

function sum(...numbers) {
    return numbers.reduce((a, b) => a + b, 0);
}
console.log(sum(1, 2, 3)); // 6

const arr1 = [1, 2];
const arr2 = [...arr1, 3, 4];
console.log(arr2); // [1, 2, 3, 4]

Enter fullscreen mode Exit fullscreen mode
  • function sum(...numbers) declares a function named sum that uses a rest parameter ...numbers.
  • The rest parameter ...numbers allows the function to accept any number of arguments and gathers them into an array named numbers.
  • numbers.reduce(...) applies the reduce method on the numbers array.
  • The reduce method iterates over each element in the numbers array and accumulates a single value (a + b).
  • (a, b) => a + b is an arrow function that adds two numbers a and b.
  • 0 is the initial value of a in the reduction process.
  • sum(1, 2, 3) calls the sum function with three arguments: 1, 2, and 3.
  • The function calculates the sum of these numbers (1 + 2 + 3) using reduce.
  • The result 6 is logged to the console.
  • const arr1 declares a constant variable arr1 initialized with an array [1, 2].
  • ...arr1 spreads the elements of arr1 into the new array arr2.
  • [...arr1, 3, 4] creates a new array arr2 by combining the elements of arr1 (1 and 2) with 3 and 4.
  • console.log(arr2) outputs the contents of arr2 to the console.
  • The output displayed is [1, 2, 3, 4], which is the combined array with elements from arr1 and additional elements 3 and 4.

7. Classes

Classes provide a more intuitive and simpler syntax for creating objects and dealing with inheritance in JavaScript. Use classes to create objects and establish inheritance hierarchies.

Example:

class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }

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

const john = new Person('John', 30);
john.greet(); // Hello, my name is John and I am 30 years old.

Enter fullscreen mode Exit fullscreen mode
  • class Person declares a new class named Person.
  • Classes in JavaScript provide a way to define blueprints for creating objects with shared methods and properties.
  • The constructor method is a special method for creating and initializing objects created with a class.
  • constructor(name, age) defines parameters name and age.
  • this.name = name; assigns the value of name passed to the constructor to the name property of the object being created (this refers to the current instance of the Person class).
  • this.age = age; assigns the value of age passed to the constructor to the age property of the object being created.
  • greet() defines a method greet within the Person class.
  • Methods in classes are functions that can be called on instances of the class.
  • Template literals (enclosed in backticks `) allow embedding expressions inside strings.
  • ${this.name} and ${this.age} are expressions that are replaced with the values of name and age properties of the current object (this refers to the current instance of Person).
  • new Person('John', 30) creates a new instance of the Person class.
  • The constructor method is automatically called with arguments 'John' and 30, initializing the name and age properties of the john object.
  • john.greet() calls the greet method on the john object.
  • The method logs "Hello, my name is John and I am 30 years old." to the console, using the values stored in john.name and john.age.

8. Promises

Promises provide a way to handle asynchronous operations more gracefully than callbacks. Use promises for handling asynchronous operations such as API calls.

Example:

const fetchData = () => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('Data fetched');
        }, 1000);
    });
};

fetchData().then(data => {
    console.log(data); // Data fetched
});

Enter fullscreen mode Exit fullscreen mode
  • const fetchData declares a constant variable fetchData initialized with an arrow function () => { ... }.
  • Arrow functions provide a concise way to write functions in JavaScript.
  • new Promise(...) creates a new Promise object.
  • The Promise constructor takes a function with resolve and reject parameters.
  • Inside this function:
    • setTimeout(..., 1000) schedules a function to be executed after a delay of 1000 milliseconds (1 second).
    • The arrow function () => { resolve('Data fetched'); } is executed after the timeout.
    • resolve('Data fetched') fulfills the promise with the value 'Data fetched'.
  • fetchData() calls the fetchData function, which returns a Promise.
  • .then(data => { ... }) attaches a callback function to handle the resolved value (data) when the promise is fulfilled.
  • The arrow function data => { console.log(data); } is executed once the promise is resolved successfully (resolve('Data fetched')).
  • console.log(data) outputs the value of data ('Data fetched') to the console.

9. Async/Await

Async/await allows you to write asynchronous code in a more synchronous and readable manner.Use async/await for clearer and more readable asynchronous code.

Example:

const fetchData = () => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('Data fetched');
        }, 1000);
    });
};

async function getData() {
    const data = await fetchData();
    console.log(data); // Data fetched
}

getData();

Enter fullscreen mode Exit fullscreen mode
  • const fetchData declares a constant variable fetchData initialized with an arrow function () => { ... }.
  • Arrow functions provide a concise way to define functions in JavaScript.
  • new Promise(...) creates a new Promise object.
  • The promise executor function takes two parameters: resolve and reject.
  • Inside the executor function:
    • setTimeout(..., 1000) schedules a function to be executed after a delay of 1000 milliseconds (1 second).
    • The arrow function () => { resolve('Data fetched'); } is executed after the timeout completes.
    • resolve('Data fetched') fulfills the promise with the value 'Data fetched'.
  • async function getData() declares an asynchronous function named getData.
  • Async functions allow you to write asynchronous code in a synchronous-like manner, making it easier to work with promises and other asynchronous operations.
  • await fetchData() pauses the execution of getData until the promise returned by fetchData settles (fulfills or rejects).
  • Once fulfilled, await returns the resolved value ('Data fetched') and assigns it to the variable data.
  • console.log(data); outputs the value of data ('Data fetched') to the console.
  • getData() calls the getData function, initiating the execution of asynchronous operations defined inside getData.

Conclusion

ES6+ features provide powerful tools for writing modern JavaScript. By understanding and using these features, developers can write more efficient, readable, and maintainable code.

Top comments (0)