2021SC@SDUSC Source code analysis of "F2 mobile terminal visualization scheme" -- new features of ES11

Posted by cvjacques on Mon, 03 Jan 2022 08:25:28 +0100

2021SC@SDUSC

catalogue

matchAll

Dynamic import

import.meta

export * as ns from 'module'

Promise.allSettled

BigInt

GlobalThis

Null merge operator (?)

Optional chain operator (.?)

matchAll

The matchAll() method returns an iterator containing the results of all matching regular expressions. Use for Of traversal or using operators Array.from converts it to an array.

const reg = /[0-3]/g;
const data = "2020";
console.log(data.matchAll(reg)); //data. The return value of matchall is an iterator
console.log([...data.matchAll(reg)]);
/**
 * 0: ["2", index: 0, input: "2020", groups: undefined]
 * 1: ["0", index: 1, input: "2020", groups: undefined]
 * 2: ["2", index: 2, input: "2020", groups: undefined]
 * 3: ["0", index: 3, input: "2020", groups: undefined]
 */

Dynamic import

In the standard usage of import, the imported module is static, which will make all the imported modules compiled when loaded (on-demand compilation cannot be achieved, reducing the loading speed of the home page). In some scenarios, you may want to import modules according to conditions or on-demand. In this case, you can use dynamic import instead of static import.

if (XXX) {
  const menu = import("./menu");
}

@Babel / preset env already contains @ Babel / plugin syntax dynamic import. Therefore, if you want to use the import() syntax, you only need to configure @ Babel / preset env.

In addition, webpack already supports dynamic import.

Actual use case of dynamic import of webpack Click here to view.

In addition, import() returns a promise object.

import.meta

import.meta will return an object with a url attribute and return the url path of the current module. It can only be used inside the module.

<script src="./main.js" type="module"></script>


// main.js
console.log(import.meta);
// {url: "http://localhost:8080/main.js"}
// PS: started using HTTP server

Because import Meta must be used inside the module. If type="module" is not added, the console will report an error: cannot use 'import meta' outside a module.

During the actual operation of the project, @ Babel / preset Env, @ Babel / preset react, and @ open WC / webpack import meta loader need to be configured

And modify the webpack configuration

module: {
  rules: [
    {
      test: /\.js$/,
      use: [
        require.resolve("@open-wc/webpack-import-meta-loader"),
        {
          loader: "babel-loader",
          options: {
            presets: ["@babel/preset-env", "@babel/preset-react"],
          },
        },
      ],
    },
  ];
}

The effects are as follows:

// src/index.js
import React from "react";
console.log(import.meta);
// {index.js:38 {url: "http://127.0.0.1:3000/src/index.js"}}

export * as ns from 'module'

ES2020 adds export as XX from 'module' and import as XX from 'module'

//menu.js
export * as ns from "./info";

import * as ns from "./info";
export { ns };
 

However, it should be noted that export * as ns from '/ info 'will not really be'/ info 'imports the module, so we can't get ns in this module (menu.js).

Promise.allSettled

Sometimes promise needs to be processed in the project, such as promise all, Promise.then, Promise.finally,Promise.race. However, the above can not meet all the needs of the business. For example, when we need to do some operations at the end of all promises, we don't care whether they succeed or fail. You can now use promise Allsettled

const promise1 = Promise.resolve(100);
const promise2 = new Promise((resolve, reject) =>
  setTimeout(reject, 100, "info")
);
const promise3 = new Promise((resolve, reject) =>
  setTimeout(resolve, 200, "name")
);

Promise.allSettled([promise1, promise2, promise3]).then((results) =>
  console.log(result)
);
/* 
    [
        { status: 'fulfilled', value: 100 },
        { status: 'rejected', reason: 'info' },
        { status: 'fulfilled', value: 'name' }
    ]
*/

As you can see, promise The successful result of allsettled() is an array. Each item of the array is an object. Each object has a status attribute with the value of fully or rejected. If the value of status is fully, the object also has a value attribute, and its attribute value is the result of the success of the corresponding promise; If the value of status is rejected, the object has a reason attribute whose value is the reason for the corresponding promise failure.

BigInt

BigInt is a numeric type of data that can represent integers in any precision format. Before that, the maximum safe number in JS was 9009199254740991, i.e. 2 ^ 53-1. Enter number in the console MAX_ SAFE_ Integer to view. Beyond this value, JS cannot express it accurately. In addition, JS cannot represent a value greater than or equal to the 1024 power of 2, and Infinity will be returned.

BigInt solves these two problems. BigInt is only used to represent integers. There is no limit on the Number of bits. Integers with any Number of bits can be accurately represented. In order to distinguish from the Number type, the data of BigInt type must be suffixed with n

//When the Number type exceeds 9009199254740991, there is a problem with the calculation result
const num1 = 90091992547409910;
console.log(num1 + 1); // 90091992547409900

//BigInt calculation result is correct
const num2 = 90091992547409910n;
console.log(num2 + 1n); // 90091992547409911n


//The Number type cannot represent a value greater than 2 to the 1024 power
let num3 = 9999;
for (let i = 0; i < 10; i++) {
  num3 = num3 * num3;
}
console.log(num3); // Infinity

//The BigInt type can represent an integer of any number of digits
let num4 = 9999n;
for (let i = 0n; i < 10n; i++) {
  num4 = num4 * num4;
}
console.log(num4); // Equal to a long string of numbers~


We can also use BigInt Object to initialize BigInt example:



console.log(BigInt(999)); // 999n

It should be noted that BigInt and Number are two data types, and can not directly perform four operations, but can be compared.

console.log(99n == 99); //true
console.log(99n === 99); //false
console.log(99n + 1);
//TypeError: Cannot mix BigInt and other types, use explicit conversionss

GlobalThis

There is a top-level object in JS, but the top-level object is not unified in various implementations.

Getting global objects from different JavaScript environments requires different statements. In the Web, you can get global objects through window and self, but in Web Workers, only self can. On node JS, they cannot be obtained, and global must be used.

globalThis is provided in ES 11. In any environment, you can simply get the top-level objects through globalThis.

Null merge operator (?)

ES2020 adds an operator??. When the left operand is null or undefined, the right operand is returned; otherwise, the left operand is returned.

Using the | operator, when the operands on the left are 0, null, undefined, NaN, false and '', the operands on the right will be used. If you use | to set default values for some variables, you may encounter unexpected results.

const defaultValue = 100;
let value = someValue || defaultValue;
//When someValue is converted to boolean and the value is false, the values of value are all defaultvalues

When the value of someValue is 0, we actually expect the value to be 0, but it is incorrectly assigned to 100

?? Operator can avoid the above problems. It returns the right operand only when the left operand is null or undefined.

const defaultValue = 100;
let value = someValue ?? defaultValue;
//someValue is 0 and value is 0

Optional chain operator (.?)

Optional chain operator Allows you to read the value of an attribute located deep in the chain of connected objects without explicitly verifying that each reference in the chain is valid The function of the operator is similar to The difference of chain operator is that it will not cause an error when the reference is null or undefined. The short circuit return value of the expression is undefined.

For example, we want to access the tortoise of reptile of animal of info object. However, we are not sure whether animal and reptile exist, so we need to write as follows:

const tortoise =
  info.animal && info.animal.reptile && info.animal.reptile.tortoise;

Because null Duplicate or undefined Reptile will throw an error: TypeError: Cannot read property 'reptile' of undefined or TypeError: Cannot read property 'reptile' of null. In order to avoid error reporting, if we need to access deeper properties, the code will be longer and longer.

And with the optional chain operator, Before accessing reptile, we no longer need to verify info The value of animal. Similarly, visit info animal. reptile. Before tortoise, there is no need to verify info animal. The value of reptile.

const tortoise = info.animal?.reptile?.tortoise;

JS is trying to access info animal. Before replile, it implicitly checks and determines info The value of animal is not null or undefined. If its value is null or undefined, the expression short circuit calculation directly returns undefined.

You can see the optional chain operator Like the vacancy merge operator, both are for null and undefined values.

Topics: Javascript Vue.js Webpack