It's time to come. There are new features in ES12!

Author: KUMAR HARSH
Translator: front end Xiaozhi
Source: blog

There are dreams and dry goods. Wechat search [Daqian world] pays attention to this bowl washing wisdom who is still washing dishes in the early morning.

This article GitHub https://github.com/qq449245884/xiaozhi It has been included. There are complete test sites, materials and my series of articles for the interview of front-line large factories.

Today, I will mainly introduce some JS functions 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 will the logical operation (& &, |, or?) Combined with an assignment expression.

x ||= y;
x || (x = y);

x &&= y;
x && (x = y);


x ??= y;
x ?? (x = y);

Logical assignment operator with & &

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

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

Or equivalent to

if(x) {
  x = y
}

Because x is a true value, it is assigned y, that is, 2.

Logical assignment operator with 𞓜

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

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

This means that the assignment operation only occurs when x is a virtual value. In our code, X contains 1, which is a true value, so the assignment will not occur. This is why our code prints 1 in the console.

Simply put

const updateID = user => {

  // We can do this
  if (!user.id) user.id = 1

  // Or so
  user.id = user.id || 1

  // Or so
  user.id ||= 1
}

have?? Logical assignment operator

?? Check whether a value is null or undefined in JS.

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

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

Now consider?? And = =.

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

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

Number separator

It allows us to underline () between numbers Characters to make numbers more readable.

for example

const num = 100000000

Confused by the number of 0

Delimiters solve this problem:

const num = 100_000_000

Separators can be used for integer and decimal parts of numbers.

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"

Separators are for readability only. Therefore, it can be placed anywhere in 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 are passed to promise If promise with any () as a parameter (as an array) is rejected, an "AggregateError" exception is thrown.

AggregateError ` is a new subclass of Error that groups individual errors. Each AggregateError instance contains a reference to the exception array.

Consider the following example:

Below we have three promise s, 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 one is completed by promise Any() execute.

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

What if all 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, in promise We can only use one promise in any(). And this promise failed. The above code records the following error in the console.

String.prototype.replaceAll method

String.prototype.replaceAll() allows us to replace all substring instances in a string with a different value without using a global regular expression.

Currently, JavaScript strings have a replace() method. It can be used to replace a 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. This is why the second occurrence of "Back" in the code is not replaced.

A complete replacement is possible only 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 the source of errors. (no one likes RegEx 😬)

Another way is to use string prototype. Split() and array prototype. Join() method

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

This method avoids regular expressions, but you must split the string into separate parts (words), convert it into an array, and then connect the array elements into a new string.

string.prototype.replaceAll() solves these problems and provides a simple and convenient way to globally replace substrings:

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

Note: if you use a global regular expression as the lookup value, replace and replaceAll behave the same.

WeakRefs and FinalizationRegistry objects

WeakRef means weak reference. The main purpose of weak references is to cache or map large objects. In this case, we don't want to keep a lot of memory for a long time to save this rarely used cache or mapping. We can make the memory garbage collected quickly. Later, if we need it again, we can generate a new cache.

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

WeaseRefs (weak references) provides two new features:

  • Use the WeakRef class to create a weak reference to an object
  • 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, inter Alia, remove references to objects that have been "cleaned up" by the garbage collector.

This technique may be useful when creating a memoization function using a built-in cache if there are calculated values of the parameters passed to the function in the cache (provided that the objects are used as attribute values of the cached objects and the risk that they will be deleted later) to prevent repeated execution of the function.

When building inline cache

  • If there is no risk of memory leakage, use Map
  • When using keys that can subsequently delete objects, use WeakMap
  • When using value objects that can be deleted later, use Map with WeakRef

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);
  • The WeakRef constructor accepts a parameter that must be an object and returns a weak reference to the object

  • The deref method of the WeakRef instance returns one of the two values.

In the case of built-in cache, the finalizer is designed to complete the cleaning process after a value object is destroyed by the garbage collector, or more simply, delete 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);

~After that, I'm Xiao Zhi. I'm coughing. I'm going to have a rest. Record some praise and attention, and get rich.

Original text: https://dev.to/cenacr007_harsh/es2021-features-3pa

communication

The article is continuously updated every week. You can search * * [Daqian world] on wechat to read it for the first time and reply to [welfare] * * there are many front-end videos waiting for you. This article GitHub https://github.com/qq449245884/xiaozhi Already included, welcome Star.

Keywords: Javascript Front-end Vue

Added by olygolfer on Mon, 17 Jan 2022 18:39:03 +0200