Introduction

ES11 is a version issued by the ECMA Association in June 2020. Because it is the eleventh version of ECMAScript, it is also called ES11.

Today we explain the new features of ES11.

ES11 introduces 9 new features, we will explain them one by one next.

Dynamic imports

Before ES11, we can use the following methods to import modules:

import * as TestModule from "./test-module.js";

However, there are some problems with the above import method. The first is efficiency. All modules need to be imported when they are loaded for the first time, which will reduce the efficiency of the program. In addition, the module name above is hard-coded and cannot be dynamically modified while the program is running.

That is to say, the above module import method cannot dynamically import the module or import it on demand, which has many inconveniences in use.

In order to solve this problem, ES11 introduced a new import() method. Using this method, you can dynamically import modules, and by setting the module name in the form of variables, you can dynamically modify the module name, which is very magical. Let's look at a specific usage example:

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

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

In the above code, we define a basic Module path. By clicking the button on the page, a users.js module can be dynamically loaded, and then the getUsers() method of the module can be called to obtain the userList list.

import.meta

In addition to dynamically importing modules, import also provides a meta attribute, which contains the information of the currently imported module. Currently, there is a url attribute in it, which represents the URL to which the module is referenced. If you want to use URL information, you can use import.meta.url in your code.

export strengthening

Import was introduced in ECMAScript 2015 and is mainly used to import modules. Import can import the entire module or part of the module. As follows:

import {something} from "./test-module.js";
import * from "./test-module.js";

Corresponding to import is export. You can also export all or part of it, as shown below:

export {something} from "./test-module.js";
export * from "./test-module.js";

Generally speaking, the import and export mentioned above are enough, but for the case where the export module needs to be renamed, we cannot export directly, but must first rename it when importing, and then use export to rename The module export:

import * as myModule from "./test-module.js";
export {myModule};

If you use the enhancement of export, you do not need to use import, just use export directly to export:

export * as {myModule} from "./test-module.js";

BigInt

ES11 introduced a new data type BigInt. Prior to this, the object representing numbers in javascript was Number, which can represent 64-bit floating-point numbers. Of course, it can also represent an integer, but the maximum value represented by an integer is 2^53, which can also be represented by Number.MAX_SAFE_INTEGER.

Generally, Number is enough, but if in some cases 64-bit integers need to be stored or calculated, or the range to be expressed exceeds 64-bit, Number is not enough.

How to do it? If it is only stored, it can be stored as a string, but the second type of string is not applicable. So BigInt was introduced to solve this problem. To represent BigInt, just add n after the number.

const bigInt = 112233445566778899n;

Or use the constructor to construct bigInt:

const bigInt = BigInt("112233445566778899");

You can use typeof to view the type of bigInt. It should be noted that although Number and BigInt both represent numbers, the two cannot be mixed. You cannot add a Number and a BigInt. This will report a TypeError exception.

If you have to operate, you can use the BigInt constructor to convert Number to BigInt before proceeding.

matchAll()

Regular expression matching is a very common operation. Usually we use regExp.exec to perform regular matching. An example of regular expression is as follows:

const regExp = /yyds(\d+)/g;
const text = 'yyds1 is a very good yyds2';
let matches;

while ((matches = regExp.exec(text)) !== null) {
  console.log(matches);
}

The results of the above code running are as follows:

["yyds1","1"]
["yyds2","2"]

We got all matching values. However, it needs to use a loop to traverse, which has a lot of inconvenience to use. For the sake of simplicity, ES11 introduces the matchAll() method. This method can simply return a iterator. By traversing this iterator, you can get all the matching values, as shown below:

const regExp = /yyds(\d+)/g;
const text = 'yyds1 is a very good yyds2';
let matches = [...text.matchAll(regExp)];

for (const match of matches) {
  console.log(match);
}

globalThis

For javascript, the way to obtain global objects corresponding to different environments is also different. For browsers, windows are usually used, but self is used in web workers, and global is used in nodejs.

In order to solve the problem of different global objects in different environments, ES11 introduces globalThis. Through this global object, programmers no longer need to distinguish which environment they are in. They only need to use globalThis.

Promise.allSettled()

Since the introduction of Promises, there are two methods to combine Promises, namely Promise.all() and Promise.race(), which respectively represent the return of all Promises and the fastest one.

For Promise.all(), it will wait for all of the Promises to complete and return. If one of the Promises is rejected, then the entire Promise.all() will be rejected. In this case, if one Promise is rejected, the results of other Promises will not be obtained.

To solve this problem, ES11 introduced the Promise.allSettled() method. This method will wait for all Promises to end, regardless of whether they are rejected, so you can use the following code to get all the results, regardless of whether there is a Promise problem.

const promises = [promise1("/do1"), promise2("/do2")];
const allResults = await Promise.allSettled(promises);
const errors = results
  .filter(p => p.status === 'rejected')
  .map(p => p.reason);

?? operator

The ?? operator is an operation that determines whether it is empty and then assigns a value. If there is no such operator, we usually use || to simply perform this operation, as shown below:

const yourAge = someBody.age || 18

The above code means that if someBody.age is empty, then set yourAge to 18.

But there is a problem with the above code. If someBody.age=0, the above logic also holds. use? ? Operators can solve this problem.

const yourAge = someBody.age ?? 18

?. Operator

Sometimes when we get the properties of an object, we need to make a null judgment of the object, otherwise an error will be reported when the property is taken out of the null object, but the usual ?: operator is too complicated to use, if there are multiple objects and This is especially true in the case of attribute chaining. If you use the ?. operator, it will be much simpler:

const age = school?.class?.student?.age;

As shown above, this is a very complicated continuous write operation, but using ?. becomes very simple.

The same?. Can also be used on object methods:

const age = student.getAge?.();

The above code indicates that if the student's getAge method exists, it will be called, otherwise it will return undefined.

Summarize

In fact, all modern browsers basically support ES11, except IE. You can try out the new features of ES11.

This article has been included in http://www.flydean.com/ecmascript-11/

The most popular interpretation, the most profound dry goods, the most concise tutorial, and many tips you don't know are waiting for you to discover!

Welcome to pay attention to my official account: "Program those things", know technology, know you better!


flydean
890 声望437 粉丝

欢迎访问我的个人网站:www.flydean.com