4
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).

  1. logical assignment operator
  2. Number separator (1_000)
  3. Promise.any and AggregateError
  4. String.prototype.replaceAll
  5. 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.

image.png

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 and replaceAll 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 objects
  • WeakRef combination with Map 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 object
  • deref 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.


王大冶
68.1k 声望105k 粉丝