Author: KUMAR HARSH
Translator: Front-end Xiaozhi
Source: blog
If you have dreams and dry goods, search on [Moving the World] still washing dishes in the early morning.
This article https://github.com/qq449245884/xiaozhi , and there are complete test sites, materials and my series of articles for interviews with first-tier manufacturers.
Today, I will mainly introduce the JS functions that are part of ECMAScript 2021 (ES12).
- logical assignment operator
- Number separator (1_000)
- Promise.any and AggregateError
- String.prototype.replaceAll
- WeakRefs and FinalizationRegistry objects
logical assignment operator
The logical assignment operator combines a logical operation ( &&
, ||
or ??
) with an assignment expression.
x ||= y;
x || (x = y);
x &&= y;
x && (x = y);
x ??= y;
x ?? (x = y);
with &&
logic evaluation operator
let x = 1;
let y = 2;
x &&= y;
console.log(x); // 2
x &&= y
equivalent to x && (x = y)
.
or equivalently
if(x) {
x = y
}
Because x
is a true value, it is assigned the value y
, which is 2
.
Logical assignment operator with ||
let x = 1;
let y = 2;
x ||= y;
console.log(x); // 1
x ||= y
equivalent to x || (x = y)
.
This means that the assignment will only happen if x
In our code, x
contains 1
, which is a true value, so the assignment doesn't happen. That's why our code prints 1
in the console.
general speaking
const updateID = user => {
// 我们可以这样做
if (!user.id) user.id = 1
// 或者这样
user.id = user.id || 1
// 或者这样
user.id ||= 1
}
Logical assignment operator with ??
??
specifically checks in JS whether a value is null
or undefined
.
let a;
let b = a ?? 5;
console.log(b); // 5
In the second row, let b = a ?? 5
, if a
value null
or undefined
, ??
evaluated and assigned to b
.
Now consider ??
and ==
.
let x;
let y = 2;
x ??= y;
console.log(x); // 2
x ??= y
equivalent to x = x ?? (x=y)
number separator
It allows us to add underscore ( _
) characters between numbers to make numbers more readable.
For example
const num = 100000000
Confused by the number of 0s
Separator solves this problem:
const num = 100_000_000
Separators can be used for the integer and fractional parts of numbers.
const num = 1_000_000.123_456
Delimiters can be used not only in integers and floating point numbers, but also in binary, hexadecimal, and octal literals.
Separator also works for BigInt numbers.
const trillion = 1000_000_000_000n;
console.log(trillion.toString()); // "1000000000000"
The delimiters are just for readability. So, it can be placed anywhere inside the number.
const amount = 178_00; // 00 after _ for cents.
Promise.any and AggregateError
Promise.any()
returns the value of the first fulfilled promise. If all Promise.any()
passed to 061e9f78beb84d as arguments (as an array) are rejected, a " AggregateError
" exception is thrown.
AggregateError` is a new Error subclass that groups individual errors. Each AggregateError instance contains a reference to an array of exceptions.
Consider the following example:
Below we have 3 promises which are random.
const p1 = new Promise((resolve, reject) => {
setTimeout(() => resolve("A"), Math.floor(Math.random() * 1000));
});
const p2 = new Promise((resolve, reject) => {
setTimeout(() => resolve("B"), Math.floor(Math.random() * 1000));
});
const p3 = new Promise((resolve, reject) => {
setTimeout(() => resolve("C"), Math.floor(Math.random() * 1000));
});
Among p1
, p2
and p3
, the first completed is executed Promise.any()
(async function() {
const result = await Promise.any([p1, p2, p3]);
console.log(result); // 打印 "A", "B" 或者 "C"
})();
Promise.any()
fail? In this case, 061e9f78beb910 throws AggregateError
exception.
We need to capture it:
const p = new Promise((resolve, reject) => reject());
try {
(async function() {
const result = await Promise.any([p]);
console.log(result);
})();
} catch(error) {
console.log(error.errors);
For demonstration purposes, in Promise.any()
we can only have one promise
. And this promise fails. The above code logs the following error in the console.
String.prototype.replaceAll method
String.prototype.replaceAll()
allows us to replace all instances of substrings in a string with a distinct value without using global regular expressions.
Currently, JavaScript strings have a replace()
method. It can be used to replace one string with another string.
const str = "Backbencher sits at the Back";
const newStr = str.replace("Back", "Front");
console.log(newStr); // "Frontbencher sits at the Back"
If the input pattern is a string, the replace()
method replaces only the first occurrence. That's why in the code, Back
" is not replaced.
Full replacement is only possible if the pattern is provided as a regular expression.
const str = "Backbencher sits at the Back";
const newStr = str.replace(/Back/g, "Front");
console.log(newStr); // "Frontbencher sits at the Front"
Let's look at another example
const strWithPlus = '++'
const strWithComma = strWithPlus.replace(/+/g, ', ')
// , ,
This method requires the use of regular expressions. However, complex regular expressions are often a source of errors. (Nobody likes RegEx 😬)
Yet another method is to use the String.prototype.split()
and Array.prototype.join()
methods
const strWithPlus = '++'
const strWithComma = strWithPlus.split('+').join(', ')
// , ,
This approach avoids using regular expressions, but has to split the string into individual parts (words), convert it to an array, and then concatenate the array elements into a new string.
string.prototype.replaceAll()
solves these problems and provides a simple and convenient way to replace substrings globally:
const strWithPlus = '++'
const strWithComma = strWithPlus.replaceAll('+', ', ')
// , ,
replace
andreplaceAll
behave the same if a global regular expression is used as the lookup value.
WeakRefs and FinalizationRegistry objects
WeakRef
means weak reference. The main purpose is to achieve large-scale weak reference object cache or mapping . In this case, we don't want to keep a large amount of memory long-term to hold such rarely used caches or maps. We can make the memory garbage collected very quickly, and later if we need it again, we can generate a new cache.
JS is automatically garbage collected. If a variable is no longer reachable, the JS garbage collector will automatically delete it. You can read more about JS garbage collection MDN
WeaseRefs (weak references) provide two new features:
- Use
WeakRef
class to create weak references to objects - Use the
FinalizationRegistry
class to run a custom collector after garbage collection
In short, WeakRef
allows us to create weak references to objects that are property values of another object, and finalizers can be used to, among other things, remove references to objects that have been "cleaned up" by the garbage collector.
When creating memoization functions that use built-in caching, this technique can be useful if there are computed values in the cache for the parameters passed to the function (provided that the objects are used to cache the object's property values, and they are subsequently risk of deletion) to prevent duplicate execution of the function.
When building an inline cache
- If there is no risk of memory leak then use
Map
WeakMap
when using keys that can subsequently delete objectsWeakRef
combination withMap
with value objects that can be subsequently deleted
The last example in the proposal:
function makeWeakCached(f) {
const cache = new Map()
return key => {
const ref = cache.get(key)
if (ref) {
//
const cached = ref.deref()
if (cached !== undefined) return cached;
}
const fresh = f(key)
// ( )
cache.set(key, new WeakRef(fresh))
return fresh
};
}
const getImageCached = makeWeakCached(getImage);
WeakRef
constructor takes one parameter, which must be an object, and returns a weak reference to that objectderef
method of the WeakRef instance returns one of two values.
In the case of the built-in cache, finalizer
is designed to complete the cleanup process after a value object is destroyed by the garbage collector, or, more simply, to remove weak references to such an object.
function makeWeakCached(f) {
const cache = new Map()
// -
const cleanup = new FinalizationRegistry(key => {
const ref = cache.get(key)
if (ref && !ref.deref()) cache.delete(key)
})
return key => {
const ref = cache.get(key)
if (ref) {
const cached = ref.deref()
if (cached !== undefined) return cached
}
const fresh = f(key)
cache.set(key, new WeakRef(fresh))
// ( )
cleanup.register(fresh, key)
return fresh
}
}
const getImageCached = makeWeakCached(getImage);
~End, I'm Xiao Zhi, I'm coughing continuously, I'm going to rest, record likes, follow, and get rich.
Original: https://dev.to/cenacr007_harsh/es2021-features-3pa
possible bugs after the code is deployed cannot be known in real time. In order to solve these bugs afterwards, a lot of time is spent on log debugging. By the way, I recommend a useful bug monitoring tool Fundebug .
comminicate
The article is continuously updated every week, you can search [Big Move to the World] Read it for the first time, reply [Welfare] has many front-end videos waiting for you, this article GitHub https://github.com/qq449245884/xiaozhi has been included, welcome to Star.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。