By Kumar Harsh


Translator: front end little wise


Source: the blog

Have a dream, have dry goods, WeChat search [big move world] keep an eye on this washing dishes in the wee hours of the morning.

This paper making https://github.com/qq449245884/xiaozhi has included, has a complete line companies interview examination site, information, and my series of articles.

Today I’ll cover some of the JS features of ECMAScript 2021 (ES12).

  1. Logical assignment operator
  2. Numeric separator (1_000)
  3. Promise. Any and AggregateError
  4. String.prototype.replaceAll
  5. WeakRefs and FinalizationRegistry object

Logical assignment operator

Logic assignment operator will logic operation (&&, | | or??) Combined with an assignment expression.

x ||= y; x || (x = y); x &&= y; x && (x = y); x ?? = y; x ?? (x = y);

with&&The logical assignment operator for the

let x = 1; let y = 2; x &&= y; console.log(x); / / 2

X &&= y is the same thing as x && (x = y).

Or it’s equivalent to

if(x) {
  x = y
}

Since x is a truth value, it is assigned the value y, which is 2.

with||The logical assignment operator for the

let x = 1; let y = 2; x ||= y; console.log(x); / / 1

X | | = y is equivalent to x | | (x = y).

This means that an assignment will only occur if x is virtual. In our code, x contains 1, which is a truth value, so assignment does not occur. That’s why our code prints 1 in the console.

In simple terms

Const updateID = user => {// We can do this if (! User. The user id). Id = 1 / / or so that the user id =. User id | | 1 / / or the user. The id | | = 1}

with??The logical assignment operator for the

?? In JS specifically check if a value is null or undefined.

let a; let b = a ?? 5; console.log(b); / / 5

In the second line, let b = a?? If a is null or undefined,?? Evaluate it and assign it to b.

Now consider? And = =.

let x; let y = 2; x ?? = y; console.log(x); / / 2

x ?? Is equal to y is equivalent to x is equal to x?? (x=y)

Numeric separator

It allows us to add underscore (_) characters between numbers to make them more readable.

For example,

const num = 100000000

Confused by the number of zeros

The delimiter solves this problem:

const num = 100_000_000

Separators can be used for the integer and decimal parts of a number.

Const num = 1 _000_000. 123 _456

Separators can be used not only in integers and floating-point numbers, but also in binary, hexadecimal, and octal literals.

The delimiter also applies to Bigint numbers.

const trillion = 1000_000_000_000n; console.log(trillion.toString()); / / "1000000000000"

The delimiters are for readability only. So, it can be anywhere within the number.

const amount = 178_00; // 00 after _ for cents.

Promise. Any and AggregateError

Promise.any() returns the value of the first completed Promise. If all Promises passed to Promise.any() as an argument (as an array) are rejected, an “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:

Here we have three 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));
});

In P1, P2, and P3, the first completion is performed by Promise.any().

(async function() { const result = await Promise.any([p1, p2, p3]); console.log(result); // Print "A", "B" or "C"})();

What if all the promises fail? In this case, Promise.Any () throws an 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, we can only use one Promise in Promise.any(). And that promise was a failure. The code above records the following errors in the console.

String. The prototype. The replaceAll method

String. The prototype. The replaceAll () allows us to use a different value all the substring in the replacement String as an example, and do not need to use the global regular expressions.

Currently, JavaScript strings have a replace() method. It can be used to replace one string with another.

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 what appears the first time. This is why the second occurrence of “Back” in the code is not replaced.

Only if a pattern is provided as a regular expression can a full replacement be made.

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 approach requires the use of regular expressions. However, complex regular expressions are often a source of errors. (Nobody likes RegEx 😬)

Another option is to use the string.prototype.split () and Array.prototype.join() methods

const strWithPlus = '++'
const strWithComma = strWithPlus.split('+').join(', ')
// , , 

This approach avoids the use of regular expressions, but you must split the string into separate parts (words), convert it to an array, and then concatenate the array elements into a new string.

String. The prototype. The replaceAll () solve these problems, and provides the global replace substring is simple and convenient way to:

const strWithPlus = '++'
const strWithComma = strWithPlus.replaceAll('+', ', ')
// , ,

Note: If you use the global regular expression as the lookup value, then
replaceand
replaceAllThe behavior is the same.

WeakRefs and FinalizationRegistry object

Weakref means weak reference. The main use of weak references is to cache or map large objects. In this case, we don’t want to keep a large amount of memory for a long time to hold this rarely used cache or map. We can get the memory quickly garbage-collected so that if we need it again later, we can generate a new cache.

JS is automatic garbage collection. If a variable is no longer reachable, the JS garbage collector will automatically remove it. You can read more about JS garbage collection in MDN.

WesterEFS (weak references) provides two new features:

  • useWeakRefClass creates a weak reference to an object
  • useFinalizationRegistryClass runs a custom collector after garbage collection

In short, WeakRef allows us to create weak references to objects that are the property values of another object, and Finalizers can be used, among other things, to remove references to objects that have been “cleaned” by the garbage collector.

When creating memoization functions that use the built-in cache, this technique can be useful if there are computed values for the parameters passed to the function in the cache (provided that the objects are used as the attribute values of the cached objects and there is a risk that they will be subsequently deleted) to prevent the function from being executed repeatedly.

When building the inline cache

  • If there is no risk of a memory leak, then useMap
  • Used when using a key that can subsequently delete an objectWeakMap
  • When using a value object that can be later deleted, setMapwithWeakRefUse a combination of

One last example from 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);
  • WeakRefThe constructor takes a parameter, which must be an object, and returns a weak reference to that object
  • Instances of WeakRefderefMethod returns one of two values.

In the case of built-in caching, finalizers are designed to complete the cleanup process after a value object has been 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);

~ over, I am small wisdom, coughing, I have to go to rest, record thumb up attention, rich oh.


Original: https://dev.to/cenacr007_hars…

communication

Article continuously updated every week, you can search the first big move world 】 【 WeChat time reading, reply [welfare] how a front-end video, waiting for you, in this paper, making https://github.com/qq449245884/xiaozhi has included, welcome Star.