ES2020 is the equivalent version of ECMAScript for 2020
String.protype.matchAll
Scene:
- Gets a match for a substring in the original string
- And the subscript position of the matching term
- Re matches grouped in the original string
Previously it could only be retrieved through the regex.exec loop
Note: ‘/g’ must be added to the re otherwise an error will be reported
The old / /
var regex = /t(e)(st(\d?) )/g;
var string = "test1test2test3";
var matches = [];
var match;
// regex.exec executes one less time
while ((match = regex.exec(string))) {
matches.push(match);
}
console.log(matches);
/ / /
// ["test1", "e", "st1", "1", index: 0, input: "test1test2test3"],
// ["test2", "e", "st2", "2", index: 5, input: "test1test2test3"],
// ["test3", "e", "st3", "3", index: 10, input: "test1test2test3"]
// ]
Copy the code
The matchAll() method returns all matches of a regular expression in the current string
However, it returns an Iterator, not an array. It is very simple to convert the iterator into an array, using… The operator and the array.from () method do the job.
const string = "test1test2test3";
const regex = /t(e)(st(\d?) )/g;
const newdata = string.matchAll(regex);
for (const match of newdata) {
console.log(match);
}
// ["test1", "e", "st1", "1", index: 0, input: "test1test2test3"]
// ["test2", "e", "st2", "2", index: 5, input: "test1test2test3"]
// ["test3", "e", "st3", "3", index: 10, input: "test1test2test3"]
// Convert to array
[...newdata];
// Convert to array
Array.from(newdata);
Copy the code
Return value resolution
First determine how many groups there are based on the number of parentheses in the regular expression,
const regex = /t(e)(st(\d?) )/g There are three groups
- The first group:
(e)
- The second group:
(st(\d?) )
- The third group:
(\d?)
[“test1”, “e”, “st1”, “1”, index: 0, input: “test1test2test3”]
- The first element of the array is the entire match.
- The second element is
(e)
Capture. - The third element is the by
(st(\d?) )
Capture. - The fourth element is the by
(\d?)
Capture. - ‘index’ is the index for the entire match (step 1) from zero.
- The ‘input’ property is the raw string being parsed.
For details, see ES Introduction -matchAll
Dynamic import
Previously the import command was a static declaration. They accept string literals as module specifiers
Only at the top level of a module, not in a code block (for example, in an if code block, or in a function)
This design, while beneficial to the compiler’s efficiency, also makes it impossible to load modules at run time. Syntactically, conditional loading is not possible
The ES2020 proposal introduces import() to support dynamic loading of modules
The import(specifier) function supports dynamic module loading. The specifier parameter to import() specifies the location of the module to be loaded.
Import () accepts whatever arguments the import command accepts, the difference being that the latter is loaded dynamically.
Import () returns a Promise object
Import () can be used anywhere, not just for modules, but also for non-module scripts. It’s run time execution, which means, when do I get to this point, it loads the specified module
Usage scenarios
Load on demand:import()
You can load a module when you need it.
const someVariable = "user";
import(`./some-modules/${someVariable}.js`)
.then((module) = > {
// Business logic
module.loadPageInto(main);
})
.catch((err) = > {
// Failed to load
});
Copy the code
Conditional loading:import()
Can be placed inif
Code blocks, depending on the situation, load different modules.
if (condition) {
import('moduleA').then(...) ; }else {
import('moduleB').then(...) ; }Copy the code
Dynamic module path:import()
Allows module paths to be generated dynamically.
import(f()) .then(...) ;Copy the code
See ES Getting Started -import for details
Promise.allSettled
There are four main methods in Promise.
name | Description | |
---|---|---|
Promise.allSettled |
1. Wait until all instances return results, no matter whetherfulfilled orrejected , the instance will end2. Sometimes, we don’t care about the result of asynchronous requests, only care about whether all requests end |
Internet ES2020 β |
Promise.all |
1. If any promise fails, the failed promise is returned. 2. When all asynchronous operations are successful, the promise is returned as an array |
Internet ES2015 β |
Promise.race |
Whenever the state of any promise changes (whether it succeeds or fails), that promise is returned | Internet ES2015 β |
Promise.any |
1. If any promise succeeds, the successful promise is returned. 2. If all promises fail/reject, return a failed promise |
Internet ES2021 β |
The promise.allsettled () method takes a set of Promise instances as parameters, wrapped as a new Promise instance. The wrapping of the instance will not end until all of these parameter instances have returned results, whether fulfilled or rejected
Sometimes, we don’t care about the result of asynchronous requests, only that all requests end. This is where the promise.allsettled () approach comes in handy
What does the word settled mean?
Stop, stop, stop, stop, stop, stop
This is fulfilled fulfilled when the promise is in a non-pending state, such as fulfilled or rejected. Then the promise would be settled
Here’s a scenario where you iterate through an array of Promises and want to return a new array with a status field (regardless of whether status represents a promise’s success or failure)
[{status: "rejected".reason: "SyntaxError: Unexpected token < in JSON at position 0"}, {status: "fulfilled".value: { success: true.data: "..."}},];Copy the code
If you use promise. all, you can only write a handler by hand
function reflect(promise) {
return promise.then(
(v) = > {
return { status: "fulfilled".value: v };
},
(error) = > {
return { status: "rejected".reason: error }; }); }const promises = [fetch("index.html"), fetch("https://does-not-exist/")];
const results = await Promise.all(promises.map(reflect));
const successfulPromises = results.filter((p) = > p.status === "fulfilled");
Copy the code
But Promise.allSettled already wrote this handler for us
async function test() {
const promises = [fetch("./index.html"), fetch("https://does-not-exist/")];
const results = await Promise.allSettled(promises);
// Filter out successful requests
const successfulPromises = results
.filter((p) = > p.status === "fulfilled")
.map((p) = > p.value);
// Filter out the failed requests and output the cause
const errors = results
.filter((p) = > p.status === "rejected")
.map((p) = > p.reason);
console.log(errors);
}
test();
Copy the code
A more realistic scenario: turn off loading after the request ends
If you use promise. all, you also need to determine the execution result
const urls = [
/ *... * /
];
const requests = urls.map((x) = > fetch(x)); // Imagine some of these will fail, and some will succeed.
// Short-circuits on first rejection, all other responses are lost
try {
await Promise.all(requests);
console.log(
"All requests have completed; now I can remove the loading indicator.",); }catch {
console.log(
"At least one request has failed, but some of the requests still might not be finished! Oops.",); }Copy the code
Use promise. alallsettlement directly
// We know all API calls have finished. We use finally but allSettled will never reject.
Promise.allSettled(requests).finally(() = > {
console.log("All requests are over, and I don't care if it succeeds or fails.");
// Disable the loading state
removeLoadingIndicator();
});
Copy the code
globalThis
Obtaining this for different environments before ES2020 requires the following encapsulation
const getGlobalThis = () = > {
// In the webworker or service worker
if (typeofself ! = ="undefined") return self;
// In the browser
if (typeof window! = ="undefined") return window;
/ / the Node. Js
if (typeof global! = ="undefined") return global;
// A separate JavaScript shell
if (typeof this! = ="undefined") return this;
throw new Error("Unable to locate global object");
};
const theGlobalThis = getGlobalThis();
if (typeoftheGlobalThis.setTimeout ! = ="function") {
// There is no setTimeout method in this environment!
}
Copy the code
Now, globalThis provides a standard way to get the globalThis object (which is the global object itself) in different environments.
if (typeofglobalThis.setTimeout ! = ="function") {
// There is no setTimeout method in this environment!
}
Copy the code
See MDN-globalThis for details
Nullish Coalescing Operator
Reason: make up for the Boolean or operator (| |) will be an empty string, 0, NaN judgment is false value
// Cannot get an empty string,0,NaN
function checkReturn0(test) {
return test || "666";
}
// It is a little troublesome
function checkReturn0(test) {
returntest ! = =undefined&& test ! = =null ? test : "666";
}
test ?? "666"Equivalent to test! = =undefined&& test ! = =null ? test : "666"
// The final solution
function checkReturn() {
return test ?? "666";
}
Copy the code
Null merge operator (??) Only if the left-hand side is zero
null
undefined
Null merge operator (??) Returns the value on the right
const baz = 0 ?? 42;
console.log(baz);
// expected output: 0
Copy the code
// 'null' check and default assignment
let test1 = null;
let test2 = test1 ?? "";
console.log("null check", test2); // Output an empty string ""
Copy the code
// 'undefined' checks and defaults to assignment
const test = undefined ?? "default";
console.log(test);
// expected output: "default"
Copy the code
// Return after comparison
/ / bad π΄
let test;
function checkReturn() {
if(! (test ===undefined)) {
return test;
} else {
return callMe("test"); }}/ / better πΆ
function checkReturn() {
return test ?? callMe("test");
}
Copy the code
Note: with the logical or operator (| |), | | will be on the left operand is false value returns the right operand
The Boolean or operator (| |) only when the left side is:
- Empty string:
' '
or` `
NaN
0
null
undefined
The Boolean or operator (| |) will return to the right of the value
var a = "" || 1;
/ / output 1
console.log(a);
Copy the code
Use the optional chain operator –? .
When looking for attribute values deep in the tree, it is usually necessary to check for the presence of intermediate nodes:
If you do not judge, you will throw an undefined variable error β
var street = user.address && user.address.street;
Copy the code
Similarly, many apis return an object or null/undefined, and may only want to extract attributes from the result if it is not null.
? .Also called chain judgment operator. It allows us to read property values deeply nested in the chain of objects without having to validate each reference. When the property does not exist, the expression stops evaluating and returns undefined
const travelPlans = {
destination: "DC".monday: {
location: "National Mall".budget: 200,}};/ / bad π΄
const res =
travelPlans &&
travelPlans.tuesday &&
travelPlans.tuesday.location &&
travelPlans.tuesday.location.href;
/ / better πΆ
/ / output is undefined
constres1 = travelPlans? .tuesday? .location? .href;Copy the code
In JS,?? Operators are called non-airfreight operators. If the first argument is not null/undefined (there are only two false values here, but the false values in JS include: Undefined undefined undefined undefined undefined undefined undefined undefined null object NULL, numeric 0, empty number NaN, Boolean false, empty string ”, don’t confuse) returns the first argument, otherwise returns the second argument. For instance,
null ?? 5; / / = > 5
3 ?? 5; / / = > 3
Copy the code
To the variable to set the default value, the commonly used before | | the Boolean or operator, for example,
const prevMoney = 1;
const currMoney = 0;
const noAccount = null;
const futureMoney = -1;
function moneyAmount(money) {
return money || 'Account not open';
}
console.log(moneyAmount(prevMoney)); / / = > 1
console.log(moneyAmount(currMoney)); // => The account is not open
console.log(moneyAmount(noAccount)); // => The account is not open
console.log(moneyAmount(futureMoney)); / / = > 1
Copy the code
Above we created the function moneyAmount, which returns the current user balance. We use the | | operator to identify without the users account. However, what does that mean when the user doesn’t have an account? It is more accurate to think of no account as empty rather than zero, since bank accounts may have no (or negative) money. In the example above, the | | operator to zero as a false value, should not include user account $0. Let’s use?? Non-airfreight operators to solve this problem:
const currMoney = 0;
const noAccount = null;
function moneyAmount(money) {
return money ?? 'Account not open';
}
moneyAmount(currMoney); / / = > 0
moneyAmount(noAccount); // => 'The account is not open'
Copy the code
To sum up…? Operator allows us to specify default values while ignoring error values such as 0 and empty strings.
The Optional Chaining operator
? .Also called chain judgment operator. It allows developers to read property values deeply nested in a chain of objects without having to validate each reference. When the reference is null, the expression stops evaluating and returns undefined. Such as:
var travelPlans = {
destination: "DC".monday: {
location: "National Mall".budget: 200,}};console.log(travelPlans.tuesday? .location);// => undefined
Copy the code
Now, put together what we’ve just learned
function addPlansWhenUndefined(plans, location, budget) {
if(plans.tuesday? .location ==undefined) {
var newPlans = {
plans,
tuesday: {
location: location ?? "Park".budget: budget ?? 200,}}; }else{ newPlans ?? = plans;// Overwrite only if newPlans is undefined
console.log("Scheduled Plan");
}
return newPlans;
}
// The initial value of the travelPlans object, from the example above
var newPlans = addPlansWhenUndefined(travelPlans, "Ford theater".null);
console.log(newPlans);
// => { plans:
// { destination: 'DC',
// Monday: {location: 'National Mall ', budget: 200}},
// Tuesday: {location: 'Ford theatre ', budget: 200}}
newPlans = addPlansWhenUndefined(newPlans, null.null);
// logs => Scheduled
// returns => newPlans object
Copy the code
The example above contains all the operators we have learned so far. We have now created a function that adds the plan to the object Tuesday. Location, which currently has no nested properties.
We also used the non-airfreight operator to provide default values. This function will mistakenly accept a value like “0” as a valid argument. This means that budget can be set to zero without any errors.
const travelPlans = {
destination: "DC".monday: {
location: "National Mall".budget: 200,}};/ / bad π΄
const res =
travelPlans &&
travelPlans.tuesday &&
travelPlans.tuesday.location &&
travelPlans.tuesday.location.href;
/ / better πΆ
/ / output is undefined
constres1 = travelPlans? .tuesday? .location? .href;Copy the code
BigInt primitive type
Older versions of the JS standard can only have a maximum integer of 2^53– that is, number.max_safe_INTEGER or math.pow (2, 53)
If you can’t accurately calculate numbers greater than 2^53
BigInt is now used to represent integers. There are no restrictions on the number of digits, and any number of digits can be accurately represented.
This is another data type in ECMAScript.
You can define a BigInt by adding n to an integer literal, such as 10n, or by calling the function BigInt().
const theBiggestInt = 9007199254740991n;
const alsoHuge = BigInt(9007199254740991);
/ / βͺ 9007199254740991 n
Copy the code
const x = Number.MAX_SAFE_INTEGER;
// βͺ 9007199254740991, this is 1 less than 2^53
const y = x + 1;
// βͺ 9007199254740992, ok, checks out
const z = x + 2;
// βͺ 9007199254740992, wait, thatβs the same as above!
Copy the code
As the above example shows, a value greater than number. MAX_SAFE_INTEGER cannot be computed,
This is where you can use BigInt
const previousMaxSafe = BigInt(Number.MAX_SAFE_INTEGER);
/ / βͺ 9007199254740991
const maxPlusOne = previousMaxSafe + 1n;
/ / βͺ 9007199254740992 n
const theFuture = previousMaxSafe + 2n;
// βͺ 9007199254740993n, this works now!
const multi = previousMaxSafe * 2n;
/ / βͺ 18014398509481982 n
constSubtr = multi -10n;
/ / βͺ 18014398509481972 n
const mod = multi % 10n;
/ / βͺ 2 n
const bigN = 2nζ―ι£54n;
/ / βͺ 18014398509481984 n
bigN * -1n
N. / / βͺ - 18014398509481984
Copy the code
- Introduction to ES – BigInt
The last
The article is shallow and humble, welcome everyone to see the comment area to leave your opinion!
Feel the harvest of students welcome to like, follow a wave!
The articles
- The most complete ECMAScript guide
- ECMAScript ES2015-ES6
- ECMAScript ES2016-ES7
- ECMAScript ES2017-ES8
- ECMAScript ES2018-ES9
- ECMAScript ES2019-ES10
- ECMAScript ES2021-ES11
- ECMAScript ES2020-ES12
- ECMAScript ES2022-ES13