10 New JavaScript Features in ES2020 That You Should Know

JavaScript continues to rapidly evolve with each passing year, and 2020 brought a number of exciting additions as part of the ECMAScript 2020 (ES2020) standard. As a developer, it‘s important to stay on top of the latest language features so you can leverage them in your projects. In this article, we‘ll cover 10 key features introduced in ES2020 that are worth learning about and putting into practice.

1. BigInt – Handling Large Integers

One of the most significant limitations of the JavaScript Number type is that it can only safely represent integers up to 2^53 – 1. But what if you need to handle much larger numbers, like when working with scientific computing or cryptography? That‘s where BigInt comes to the rescue.

BigInt is a new numeric primitive that can represent integers with arbitrary precision. You create BigInt values by appending n to the end of an integer literal:

const hugeBigInt = 123456789012345678901234567890n;

Alternatively, you can use the BigInt() constructor:

const anotherHugeBigInt = BigInt("123456789012345678901234567890");

It‘s important to note that BigInt is not backwards compatible due to its different underlying number representation. Operations between BigInt and Number values will throw a TypeError, so you need to explicitly convert between the two types when necessary.

2. Dynamic import() – Code Splitting Made Easy

Code splitting is a popular technique for improving the performance of JavaScript applications by only loading modules when they‘re actually needed. This has traditionally been accomplished using tools like webpack and Babel, but ES2020 introduces native support with the dynamic import() syntax.

With dynamic import(), you can conditionally load modules at runtime:

if (someCondition) {
  import(‘/path/to/module.js‘)
    .then((module) => {
      // Use the imported module
    })
    .catch((error) => {
      // Handle any errors that occurred during importing
    });
}

This opens up possibilities like loading modules based on user interactions or device capabilities. It also helps keep your application‘s initial bundle size smaller by deferring the loading of non-critical code.

3. Nullish Coalescing Operator – Checking for Nullish Values

The nullish coalescing operator (??) is a handy addition for checking specifically for nullish values (null or undefined) rather than falsy values in general. It returns the right-hand side operand if the left-hand side is null or undefined, otherwise it returns the left-hand side.

const result = value ?? defaultValue;

This is different from the logical OR (||) operator, which returns the right-hand side if the left-hand side is any falsy value (e.g., ‘‘, 0, false). The nullish coalescing operator is useful when you want to allow values like empty strings or false as valid.

4. Optional Chaining – Safe Property Access

Accessing nested object properties in JavaScript can be error-prone if you don‘t carefully check for the existence of each intermediate property. The optional chaining operator (?.) provides a concise and safe way to access properties without worrying about causing a TypeError if a property is missing.

const nestedValue = obj?.prop1?.prop2?.prop3;

If any of the properties in the chain are nullish (null or undefined), the expression short-circuits and returns undefined instead of throwing an error. This works not only for object properties, but also for function calls and array indexing.

5. Promise.allSettled() – Waiting for All Promises

The Promise.allSettled() method is a new addition to the Promise API that allows waiting for all promises in an array to settle, regardless of whether they fulfill or reject. It returns a promise that resolves to an array of objects representing the settlement of each promise.

const promises = [
  Promise.resolve(1),
  Promise.reject(‘Error‘),
  Promise.resolve(3),
];

Promise.allSettled(promises)
  .then((results) => {
    results.forEach((result) => {
      if (result.status === ‘fulfilled‘) {
        console.log(result.value);
      } else {
        console.error(result.reason);
      }
    });
  });

This is useful in scenarios where you want to wait for all promises to complete without short-circuiting on the first rejection, as Promise.all() does.

6. String.prototype.matchAll() – Iterating Over Regular Expression Matches

The matchAll() method is a new addition to the String prototype that provides an easy way to iterate over all matches of a regular expression, including capturing groups. It returns an iterator of match objects.

const string = ‘Hello 123 world 456‘;
const regex = /\d+/g;

for (const match of string.matchAll(regex)) {
  console.log(match);
}

This is more convenient than using the exec() method in a loop or the match() method, which only returns the first match.

7. globalThis – Accessing the Global Object

Accessing the global object in JavaScript has historically been different depending on the execution environment. In browsers, it‘s window, in Node.js it‘s global, and in web workers it‘s self. This made it cumbersome to write cross-platform code.

ES2020 introduces the globalThis property as a standardized way to access the global object in any context.

console.log(globalThis);

This simplifies writing portable JavaScript code that needs to access global variables or functions.

8. Module Namespace Exports

ES2020 introduces a symmetric syntax for importing and exporting module namespaces. Just as you can import an entire module namespace with import as name, you can now export a namespace with export as name.

// module.js
export * as utilities from ‘./utilities.js‘;

This is equivalent to importing the utilities module and then re-exporting it under the same name.

9. Standardized for-in Order

The order in which for-in loops iterate over an object‘s properties has been implementation-dependent in JavaScript. While most browsers have converged on a consistent order, it wasn‘t officially standardized until ES2020.

Now, the order of for-in iteration is defined to be the same as the order in which properties are returned by Object.keys(), with a few exceptions for special properties like prototypes and symbols.

This guarantees a reliable and predictable iteration order across different JavaScript engines.

10. import.meta – Accessing Module Metadata

The import.meta object provides a way for modules to access metadata about themselves. The most common use case is retrieving the URL of the module with import.meta.url.

console.log(import.meta.url);

This can be useful for resolving relative URLs based on the module‘s location or conditionally executing code based on the module‘s URL.

Conclusion

ECMAScript 2020 brings a host of useful features that address common pain points and make JavaScript more expressive and convenient to work with. From BigInt for handling large numbers to dynamic import() for easy code splitting, these features are worth learning and incorporating into your JavaScript projects.

As always, it‘s important to consider browser support and use appropriate polyfills or transpilation if necessary. But with the rapid adoption of new JavaScript features by modern browsers, you can start taking advantage of many of these ES2020 additions today.

JavaScript continues to evolve and improve with each ECMAScript release, and staying up to date with the latest features empowers you to write cleaner, more efficient, and more maintainable code. Embrace these new capabilities and happy coding!

Similar Posts