DEV Community

Malik-Haziq
Malik-Haziq

Posted on

Javascript new features that introduced in ECMAScript 2020

Here are some of the new features introduced in ECMAScript 2020:

Optional chaining operator (?.):

Consider the following example.

const person = {
   name: 'haziq',
   city: 'Lahore'
};

const name = person ? person.name : undefined;
Enter fullscreen mode Exit fullscreen mode

The code checking if the variable person is defined and has a property name. If person is defined and has a property name, it will assign the value of person.name to the variable name. If person is not defined or doesn't have a property name, it will assign the string 'no name' to the variable name.

But! with the help of optional chaining you'll have more compact and readable code, as shown:

const person = {
   name: 'haziq',
   city: 'Lahore'
};

const name = person?.name
Enter fullscreen mode Exit fullscreen mode

The code is using the Optional chaining operator ?. to access the property name of the object person safely. It is checking if the object person has property name if it does, it will assingn the value to variable name, if it doesn't have it will return undefined.

Nullish coalescing operator (??):

Nullish coalescing operator allows you to provide a default value when a given value is null or undefined. It is similar to the logical OR operator (||), but it only returns the right-hand side operand when the left-hand side operand is null or undefined.

Here is an example of how to use the nullish coalescing operator:

const user = { name: "John" };
console.log(user.age ?? 18); // 18
Enter fullscreen mode Exit fullscreen mode

In this example, the variable user is an object with a property name and no property age. The nullish coalescing operator (??) is used to check if the value of user.age is null or undefined. Since user.age is undefined, the right-hand side operand 18 is returned.

Dynamic imports:

Dynamic imports allows you to load a module on demand at runtime. It allows you to import a module as a function, and you can call that function to load the module.

Here is an example of how to use dynamic imports:

async function loadModule() {
  const module = await import('./module.js');
  console.log(module.default);
}
loadModule();
Enter fullscreen mode Exit fullscreen mode

In this example, loadModule() is an async function that uses the await keyword to wait for the module to be loaded before accessing it. The import() function is called with the path to the module as an argument. It returns a promise that resolves with the exports of the module.

The module.default is used to access the default export of the module.

Dynamic imports are particularly useful in situations where you only want to load a module when it's needed, rather than loading all the modules at the beginning of the application. This can improve the performance of your application by reducing the initial load time.

It's also useful for code splitting, that is, separating the application into smaller chunks that can be loaded on demand. This can reduce the amount of JavaScript that needs to be loaded and parsed on initial load, making the application faster to start and use.

bigInt:

bigint is a new primitive type that can represent integers with arbitrary precision, unlike the regular Number type, which is limited to a 53-bit integer range. The syntax for creating a bigint is to add the "n" suffix to the end of the number.
Here is an example of creating and using a bigint in JavaScript:

let bigInt = 9007199254740992n;
console.log(bigInt); // 9007199254740992n
console.log(typeof bigInt); // bigint

let sum = bigInt + 1n;
console.log(sum); // 9007199254740993n

let difference = bigInt - 1n;
console.log(difference); // 9007199254740991n
Enter fullscreen mode Exit fullscreen mode

You can also use the BigInt() function to convert a number or string to a bigint. This is useful when you're working with variables that may or may not contain bigint values:

let num = 9007199254740992;
let bigIntNum = BigInt(num);

console.log(bigIntNum); // 9007199254740992n
console.log(typeof bigIntNum); // bigint
Enter fullscreen mode Exit fullscreen mode

import meta data:

The import.meta object provides access to metadata associated with the current module. This metadata can include information about the file path, URL, and more.

The import.meta object is only available inside a module and is not available in scripts.

import.meta.url // 'file:///path/to/module.js'
Enter fullscreen mode Exit fullscreen mode

Another example, you can use import.meta to access the directory of the current module:

import.meta.dir // '/path/to/'
Enter fullscreen mode Exit fullscreen mode

You can also use import.meta to access the filename of the current module:

import.meta.filename // '/path/to/module.js'
Enter fullscreen mode Exit fullscreen mode

You can also use import.meta in dynamic import statement

import(import.meta.url.replace('.js', '-dynamic.js'))
Enter fullscreen mode Exit fullscreen mode

It's important to note that import.meta is a relatively new feature and is not yet widely supported in all JavaScript environments. It is currently supported in Node.js and modern web browsers (Chrome, Firefox, and Safari).

New export syntax:

New export syntax allows for more flexibility in how you structure and organize your code by giving you more options for exporting and importing values.

Here are a few examples of the new export syntax:

Named exports: You can use the export keyword to export a value by its name. For example:

export const name = 'John Doe';
Enter fullscreen mode Exit fullscreen mode

Default exports: You can use the export default statement to export a default value from a module. For example:

export default function add(a, b) {
    return a + b;
}
Enter fullscreen mode Exit fullscreen mode

Re-exporting: You can use the export statement to re-export a value from another module. For example:

export { name } from './module.js';
Enter fullscreen mode Exit fullscreen mode

Renaming imports and exports: You can use the as keyword to give a different name to an imported or exported value.

export { name as myName } from './module.js';
Enter fullscreen mode Exit fullscreen mode

This new export syntax provides more flexibility in structuring and organizing your code by giving you more options for exporting and importing values.

matchAll():

The matchAll() method is a string method that returns an iterator of all results matching a regular expression in a given string. It's similar to the match() method, but matchAll() returns all matches, whereas match() returns only the first match.

Here's an example of using the matchAll() method to find all occurrences of a word in a string:

let str = "The quick brown fox jumps over the lazy dog.";
let regex = /\bthe\b/gi;
let matches = str.matchAll(regex);

for (let match of matches) {
    console.log(match[0]);
}
// Output: "The" "the"
Enter fullscreen mode Exit fullscreen mode

In the above example, matchAll() method is used to find all occurrences of the word "the" in the string "The quick brown fox jumps over the lazy dog.". The for...of loop is used to iterate through the matches and print each one.

globalThis:

The globalThis object refers to the global object of the current environment, whether it be a web browser or a Node.js runtime. It provides a consistent way to access the global object regardless of the environment.

In a web browser, the globalThis object refers to the window object, which is the global object for client-side JavaScript. For example:

console.log(globalThis === window); // true
Enter fullscreen mode Exit fullscreen mode

It provides a consistent way to access the global object across different environments, and it's useful in cases where you don't know the environment in which your code will be running.

Promise.allSettled():

The Promise.allSettled() method is used to wait for an array of promises to settle (either resolve or reject). It returns a promise that is fulfilled with an array of objects that each describe the outcome of each promise.

Here's an example of using Promise.allSettled() to wait for an array of promises to settle:

let promise1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("Promise 1 resolved");
    }, 2000);
});
let promise2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        reject(new Error("Promise 2 rejected"));
    }, 1000);
});
let promise3 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("Promise 3 resolved");
    }, 3000);
});
let promises = [promise1, promise2, promise3];

Promise.allSettled(promises).then(results => {
    results.forEach(result => {
        if (result.status === "fulfilled") {
            console.log(`Promise fulfilled: ${result.value}`);
        } else {
            console.log(`Promise rejected: ${result.reason}`);
        }
    });
});
Enter fullscreen mode Exit fullscreen mode

In the above example, Promise.allSettled() is used to wait for an array of promises to settle. The then() method is used to handle the settled results. The forEach() loop is used to iterate through the results and check the status of each promise.

It's worth noting that Promise.allSettled() method is similar to Promise.all() but Promise.allSettled() waits for all promises to settle, regardless of whether they resolve or reject. Promise.all() method waits for all promises to resolve and if any promise is rejected it will cause the whole Promise.all() to reject.

It's also worth noting that features that are not supported in older environments will not throw any error but they will not work as expected and you have to check the browser support before using these features.

Top comments (3)

Collapse
 
harrysingh0071 profile image
HarrySingh0071

Keep it up

Collapse
 
harrysingh0071 profile image
HarrySingh0071

Well Done! Haziq

Collapse
 
haidernqvi profile image
haidernqvi

Help full