Захватывающие новые функции JavaScript ES12

внешний интерфейс
Захватывающие новые функции JavaScript ES12

Нажмите, чтобы перейти в личный блог, чтобы просмотреть предыдущие статьи

предисловие

13 марта 2021 г. предложение-кандидат ES2021 выпустило версию своего окончательного набора функций. Если его удастся принять на конференции ECMA в июне этого года, он станет официальным стандартом!

Ниже перечислены новые функции ECMAScript, упомянутые в этом предложении-кандидате:

  • String.prototype.replaceAll()
  • Promise.any
  • Логический оператор и выражения присваивания
  • Числовой разделитель
  • WeakRef and Finalizers

Эти новые функции вошли в фазу 4 и были добавлены в движок Google Chrome V8. Далее давайте представим эти новые функции ES2021.

String.prototype.replaceAll()

const newString = oldString.replaceAll(pattern, replacement);

Этот метод возвращает новую строку, всеpatternбудет передано емуreplacementзаменять. вpatternАргументы могут быть строками или регулярными выражениями,replacementАргументы могут быть строками или функциями, которые должны выполняться для каждого совпадения.

replaceAllпутьString.replaceПродолжение метода,String.replaceзаменить толькоpatternпервое найденное место.

const str = "Linda is a self-taught developer.Linda will rule the world";

let newStr = str.replace("Linda","Micheal")
//output: Micheal is a self-taught developer.Linda will rule the world

let newStr = str.replaceAll("Linda","Micheal")
//output: Micheal is a self-taught developer.Micheal will rule the world

В прошлом, если вам нужно было заменить все совпадающие элементы, вам приходилось писать регулярное выражение для выполнения полной замены.

const str = "hello world, hello code";
const newStr = str.replace(/hello/g, "hi");
console.log(newStr); // "hi world, hi code"

теперь естьString.prototype.replaceAll()Даже входная строка может полностью заменить совпадение.

const str = "hello world, hello code";
const newStr = str.replaceAll("hello", "hi");
console.log(newStr); // "hi world, hi code"

Promise.any

Представлено в ES6Promise.race()а такжеPromise.all() методы, добавлен ES2020Promise.allSettled(). ES2021 добавляет еще одну возможностьPromiseБолее простой способ обработки:Promise.any() Promise方法

Promise.any()получитьPromiseИтерируемые объекты, пока один изpromiseВ случае успеха вернуть тот, который был успешнымpromise(как показано в примере 1). Если у итерируемого объекта нетpromiseуспех (т.е. всеpromiseсбой/отклонение), вернуть неудавшийсяpromise а такжеAggregateErrorэкземпляр типа (как показано в примере 2), которыйErrorПодкласс , используемый для группировки одной ошибки.

Promise.any()а такжеPromise.race()Методы очень похожи, с одной лишь разницей, что не из-за определенногоPromiseОн заканчивается в отклоненном состоянии.

// 示例1
Promise.any([
  new Promise((resolve, reject) => setTimeout(reject, 200, 'Third')),
  new Promise((resolve, reject) => setTimeout(resolve, 1000, 'Second')),
  new Promise((resolve, reject) => setTimeout(resolve, 2000, 'First')),
])
.then(value => console.log(`Result1: ${value}`))
.catch (err => console.log(err))

Promise.race([
  new Promise((resolve, reject) => setTimeout(reject, 200, 'Third')),
  new Promise((resolve, reject) => setTimeout(resolve, 1000, 'Second')),
  new Promise((resolve, reject) => setTimeout(resolve, 2000, 'First')),
])
.then(value => console.log(`Result2: ${value}`))
.catch (err => console.log(err))

/**** Output ****/
// Third
// Result1: Second

В приведенном выше кодеPromise.any()Массив параметров метода содержит три операции Promise. Только один из них становитсяfulfilled,Promise.any()Возвращенный объект Promise становитсяfulfilled,а такжеPromise.race([p1, p2, p3])Какой бы результат ни был получен быстрее, он вернет этот результат, независимо от того, является ли сам результат состоянием успеха или состоянием отказа.

Если нет выполненного (успешного) обещания,Promise.any() вернуть AggregateError ошибка.

// 示例 2
const pErr1 = new Promise((resolve, reject) => {
  reject('总是失败1');
});
const pErr2 = new Promise((resolve, reject) => {
  reject('总是失败2');
});
Promise.any([pErr1,pErr2]).catch((err) => {
  console.log(err);
})

/**** Output ****/
// "AggregateError: All promises were rejected"

Логические операторы и выражения присваивания (&&=, ||=, ??=)

В JavaScript существует множество операций присваивания и логических операторов, например следующий базовый пример:

// Assignment Operator Example
let num = 5
num+=10
console.log(num) // 15
// Logical Operator Example
let num1 = 6
let num2 = 3
console.log(num1 === 6 && num2 === 2) // false
console.log(num1 === 6 || num2 === 2) // true

Новое предложение позволит нам комбинировать логические операторы с операторами присваивания.

1. Логический оператор присваивания с оператором &&

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

Операция в строке 3 эквивалентна:x && (x = y)или эквивалентно

if(x) {
  x = y
}

Поскольку x является реальным значением, присваивается значение y, равное 2. Одним словом, оператор&&=Присвойте значение переменной RHS переменной LHS, только если значение LHS истинно.

2. Операторы с || Оператор логического присваивания

Значение переменной RHS присваивается переменной LHS только в том случае, если значение LHS равно false.

// Logical Assignment Operator with || operator
let num1
let num2 = 10
num1 ||= num2
console.log(num1) // 10
// Line 4 can also be written as following ways
// 1. num1 || (num1 = num2)
// 2. if (!num1) num1 = num2

3. Логический оператор присваивания с оператором ??

ES2020 представил оператор объединения null, который также можно комбинировать с оператором присваивания. Значение переменной RHS присваивается переменной LHS только в том случае, если LHS не определено или просто имеет значение null.

// Logical Assignment Operator with ?? operator
let num1
let num2 = 10
num1 ??= num2
console.log(num1) // 10
num1 = false
num1 ??= num2
console.log(num1) // false
// Line 4 can also be written as following ways
// num1 ?? (num1 = num2)

Числовой разделитель

Мы упростим чтение числовых значений, используя символ _ (подчеркивание), чтобы обеспечить разделение между группами чисел, улучшаяудобочитаемость.

let x = 100_000; // 100000

Числовые разделители также работают для чисел BigInt.

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

Разделители предназначены только для удобства чтения. Поэтому его можно поставить в любом месте номера.

const amount = 178_00;
console.log(amount.toString()); // "17800"

WeakRef and Finalizers

Эта функция содержит два дополнительных объектаWeakRef а такжеFinalizationRegistry. В зависимости от варианта использования эти интерфейсы можно использовать по отдельности или вместе. ** Официальная рекомендация — не использовать его легкомысленно.WeakRefа такжеfinalizer. ** Одна из причин заключается в том, что они могут быть непредсказуемыми, а другая в том, что они на самом деле не выполняют работу сборщика мусора и могут фактически усложнить работу по сборке мусора.

В JavaScript, когда вы создаете ссылку, которая создает объект, эта ссылка предотвращает сборку мусора для объекта, что означает, что JavaScript не может удалить объект и освободить его память. Этот объект может существовать вечно, пока сохраняется ссылка на объект.

ES2021 имеет новые классыWeakRefs. Позволяет создавать слабые ссылки на объекты. Это позволяет отслеживать существующие объекты, не предотвращая их сборку мусора. Очень полезно для кэширования и сопоставления объектов.

должен использоватьnewключевое слово создать новыйWeakRef , и поместите какой-либо объект в круглые скобки в качестве параметров. Если вы хотите прочитать ссылку (объект, на который указывает ссылка), вы можете сделать это, вызвав слабую ссылкуderef()реализовать.

const myWeakRef = new WeakRef({
  name: '星野',
  year: '25'
})

myWeakRef.deref()
// => {  name: '星野', year: '25' }

myWeakRef.deref().name
// => '星野'

а такжеWeakRefЕсть еще другая функция тесно связана, названаfinalizersилиFinalizationRegistry. Эта функция позволяет зарегистрировать функцию обратного вызова, которая будет вызываться при сборке мусора.

// 创建 FinalizationRegistry:
const reg = new FinalizationRegistry((val) => {
  console.log(val)
})

(() => {
  // 创建新对象:
  const obj = {}

  //为 “obj” 对象注册 finalizer:
  //第一个参数:要为其注册 finalizer 的对象。
  //第二个参数:上面定义的回调函数的值。
  reg.register(obj, 'obj has been garbage-collected.')
})()
// 当 "obj" 被垃圾回收时输出:
// 'obj has been garbage-collected.'

Справочная статья