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;
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
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
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();
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
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
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'
Another example, you can use import.meta to access the directory of the current module:
import.meta.dir // '/path/to/'
You can also use import.meta to access the filename of the current module:
import.meta.filename // '/path/to/module.js'
You can also use import.meta in dynamic import statement
import(import.meta.url.replace('.js', '-dynamic.js'))
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';
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;
}
Re-exporting: You can use the export statement to re-export a value from another module. For example:
export { name } from './module.js';
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';
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"
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
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}`);
}
});
});
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)
Keep it up
Well Done! Haziq
Help full