Skip to content

Latest commit

 

History

History
159 lines (111 loc) · 6.7 KB

ES2020.MD

File metadata and controls

159 lines (111 loc) · 6.7 KB

ES2020 "ES11" credit1 credit2

See the ES2020 standard for full specification of the ECMAScript 2020 language.

ES2020 includes the following new feature proposals:


Dynamic Imports

Dynamic Imports allow to asynchronously import JS files as modules in a native way. The modules are loaded dinamically by using the “function-like” import() syntax with a dynamic specifier: import(specifier). This behaves in many ways like a function. It returns a promise for the module namespace object of the requested module, created after fetching, instantiating, and evaluating a module’s dependencies, along with the module itself. The specifier will be interpreted the same way as in an import declaration. While the specifier is a string, it is not necessarily a string literal; thus, code like import(.`/language-packs/${navigator.language}.js`) will work.

const baseModulePath = "./baseModules";
const btnImportModule = document.getElementById("btn-import-module");
let userList = [];

btnImportModule.addEventListener("click", async e => {
  const userModule = await import(`${baseModulePath}/users.js`);
  
  userList = userModule.getUsers();
});

BigInt

BigInt, a new number primitive for working with arbitrary precision integers. BigInt can represent numbers larger than two to the 53rd power—the largest number JavaScript can represent reliably with the Number primitive. A BigInt is created by appending n to the end of the integer or by calling the constructor. This implementation is not backwards compatible because the traditional number system is IEEE754 (which just cannot support numbers of this size).

let reallyBigNumber = 90071992547409920001n;
let positiveBigInt = BigInt(Number.MAX_SAFE_INTEGER); // 9007199254740991n
let negativeBigInt = BigInt(Number.MIN_SAFE_INTEGER); // -9007199254740991n

++reallyBigNumber; // 90071992547409920002n
++positiveBigInt; // 9007199254740992n
--negativeBigInt; // -9007199254740992n

typeof positiveBigInt; // "bigint"
typeof negativeBigInt; // "bigint"

Nullish Coalescing Operator (??)

Nullish coalescing is a logical operator—represented by two question marks (??)—that adds the ability to truly check nullish values (null or undefined) instead of falsey values. In the expression leftExpression ?? rightExpression, this operator returns rightExpression if leftExpression evaluates to null or undefined.

const nonNullishValue = "A non-nullish value";
const nullishValue = null;

const firstExample = nonNullishValue ?? "Fallback value"; // "A non-nullish value"
const secondExample = nullishValue ?? "Fallback value"; // "Fallback value"

Optional Chaining Operator (?.)

A property access and function invocation operator that will short-circuit if the value to access/invoke is nullish. It is a question mark (?.) followed by a dot (.). If the method/function to access/call exists, it is executed. Otherwise, the expression returns undefined.

const someObj = {
  prop: {
    subProp: {
      value: "Hello, world!"
    }
  }
};
const notAFunction = null;
const notAnArray = undefined;

someObj.prop.subProp.value; // "Hello, world!"
someObj.prop.nonExistentProp.value; // Error >> TypeError: Cannot read properties of undefined (reading 'value')

someObj?.prop?.subProp?.value; // "Hello, world!"
someObj?.prop?.nonExistentProp?.value; // undefined

notAFunction(); // Error >> TypeError: notAFunction is not a function
notAFunction?.(); // undefined


notAnArray[0]; // Error >> TypeError: Cannot read properties of undefined (reading '0')
notAnArray?.[0]; // undefined

Promise.allSettled()

The Promise.allSettled() method is a new Promise combinator that does not short-circuit. It accepts an array of Promises and only resolves when all of them are settled—either resolved or rejected.

// Shows the reason of failure of each rejected promise
const promises = [fetch("/users"), fetch("/roles")];
const allResults = await Promise.allSettled(promises);
const errors = results
  .filter(p => p.status === 'rejected')
  .map(p => p.reason);

String.matchAll()

matchAll() is a new method added to the String prototype which is related to Regular Expressions. It returns an iterator which returns all matched groups one after another.

const regExp = /[a-c]/g;
const str = "abcde";
let matches = [...str.matchAll(regExp)];

matches.forEach(match => console.log(match));
// [ 'a', index: 0, input: 'abcde', groups: undefined ]
// [ 'b', index: 1, input: 'abcde', groups: undefined ]
// [ 'c', index: 2, input: 'abcde', groups: undefined ]

globalThis

It provides a standard way of accessing the global this object across different JavaScript environments.

globalThis === window; // true

import.meta

The import.meta object contains meta information of the currently imported module. For now, the only available property is url: this will either be the URL from which the script was obtained (for external scripts), or the document base URL of the containing document (for inline scripts).

console.log(import.meta); // { url: "file:///home/user/module.js" }

Module Namespace Exports

Up until now, two separate statements were needed when exporting a module namespace—first import it and rename it, then export it. This is not the case anymore. Now, we can rename and export in a single line.

// Before
import * as moduleName from "./module.js";
export { moduleName };

// Now
export * as moduleName from "./module.js";

Standardization of for-in order

The ECMA specification had not specified the enumeration order in which for in loops should iterate. Despite browsers implemented a consistent order on their own before now, this has been officially standardized in ES2020.