Возможности, готовые к включению

Версия ECMAScript 2021, как ожидается, будет выпущена в следующем году, и теперь, когда мы завершаем эту антиутопическую версию 2020, это отличное время для обзора новых функций, которые принесут версию ES12.

Этот список основан на четвертом предложении ECMAScript, что означает, что эти функции будут в следующей версии.

Показатель

  • String.prototype.replaceAll ()
  • Promise.any ()
  • Слабые ссылки
  • Операторы логического присваивания
  • Числовые разделители

String.prototype.replaceAll ()

String.prototype.replaceAll () заменяет все экземпляры подстроки в строке другим строковым значением без использования глобального регулярного выражения.

До сих пор наиболее распространенный способ сделать это - использовать глобальное регулярное выражение.

Рассмотрим следующий код, в котором мы используем регулярное выражение для замены символа «+» пустым символом:

const fullname= 'fullname=Jhon+Hannibal+Smith';
const fullnameFormated = fullname.replace(/\+/g, ' ');
//Jhon Hannibal Smith

У этого подхода есть обратная сторона: для этого требуется регулярное выражение, в котором используются специальные символы. Но использовать регулярные выражения непросто, они подвержены ошибкам и являются частым источником ошибок.

Более простой способ решения этой проблемы - объединить String # split с Array # join:

const fullname= 'fullname=Jhon+Hannibal+Smith';
const fullnameFormated= fullname.split('+').join(' ');
//Jhon Hannibal Smith

Эта процедура позволяет избежать использования регулярных выражений, но требует разделения строки на массив частей, а затем их склеивания.

Предложение Mathias bynens решает эти проблемы и дает простой способ выполнить глобальную замену подстроки:

const fullname = 'fullname=Jhon+Hannibal+Smith';
const fullnameFormated = fullname.replaceAll('+',' ');
//Jhon Hannibal Smith

📌 Обратите внимание, что для согласованности с уже существующими API на языке String.prototype.replaceAll (searchvalue, newvalue) ведет себя как String.prototype.replace (searchvalue, newvalue) с двумя основными исключениями:

  • Если searchvalue является строкой, то String # replaceAll заменяет все вхождения, а String # replace заменяет только первое вхождение подстроки.
  • Если searchValue - неглобальное регулярное выражение, String.prototype.replace заменяет только одно совпадение. String.prototype.replaceAll, с другой стороны, вызывает исключение в этом случае, чтобы избежать путаницы между отсутствием глобального флага (что подразумевает «НЕ заменять все») и именем вызываемого метода (что предполагает « заменить все").

Promise.any ()

Promise.any () рассчитывается, как только любые обещания выполняются, или все они отклоняются. В этом случае он отклоняется с ошибкой AggregateError.

Рассмотрим следующий пример:

const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => resolve("P1"), Math.floor(Math.random() * 100));
});
const promise2 = new Promise((resolve, reject) => {
  setTimeout(() => resolve("P2"), Math.floor(Math.random() * 100));
});
(async function() {
  const result = await Promise.any([promise1, promise2]);
  console.log(result); // P1 or P2
})();

Результатом будет любой из первых разрешенных результатов Promise.any ().

В случае, если ни одно из обещаний не разрешено, Promise.any () выдает исключение и исключение AggregateError.

📌 Помните о различиях с Promise.race (), где выполняется расчет, как только выполняется какое-либо из обещаний, независимо от того, выполнены они или отклонены.

Слабые ссылки

WeakRefs полезны во многих сценариях. Например, мы можем использовать объект Map для реализации кеша с множеством ключей и значений, которым требуется много памяти. В этом случае нам удобно как можно скорее освободить память, занимаемую парами «ключ-значение», и WeakRefs позволяет нам это сделать.

Объект WeakRef содержит слабую ссылку на объект. Слабая ссылка на объект - это ссылка, которая не препятствует восстановлению объекта сборщиком мусора. С другой стороны, стандартная ссылка сохраняет объект в памяти.

Ссылки на объекты в JavaScript сохраняются. То есть, пока у вас есть ссылка на объект, он не будет собираться сборщиком мусора.

Пример:

const obj1= { a: 10, b: 20};

В настоящее время у нас есть WeakMap () и WeakSet (), которые используют WeakRefs:

Объект WeakMap - это набор пар ключ-значение, в которых ключи слабо связаны.

Рассмотрим следующий пример:

const myObj = {...};

Функция, использующая предыдущий объект:

function useTheObj(obj){
   doSomethingWith(obj);
}

Я хочу отслеживать, сколько раз метод был вызван с конкретным объектом, и сообщать, если это происходит более 1000 раз:

var map = new Map();
function useTheObj(obj){
 doSomethingWith(obj);
 //get the number of called times 
 //or initialize to 0 is null.       
 var called = map.get(obj) || 0;
 //Increase the counter in one
 called++;
 if(called > 1000) {
   console.log(’called more than 1000 times’);
 };
 map.set(obj, called);
}

Это решение работает, но у него есть утечка памяти, потому что каждый объект, переданный функции, навсегда остается на карте и не собирается сборщиком мусора. Решение - использовать WeakMap:

var wmap = new WeakMap();
function useTheObj(obj){
 doSomethingWith(obj);
 //get the number of called times
 //or initialize to 0 is null.
 var called = wmap.get(obj) || 0;
 //Increase the counter in one
 called++;
 if(called > 1000) {
   console.log(’called more than 1000 times’);
 };
 wmap.set(obj, called);
}

📌Поскольку ссылки слабые, ключи WeakMap нельзя перечислить.

📌WeakSet похож на WeakMap, но, как и в случае с наборами, каждый объект в WeakSet может встречаться только один раз. Все объекты в коллекции WeakSet уникальны.

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

Предложение оператора логического присваивания (Джастина Риджуэлла и Хеманта Х.М.) объединяет логические операторы (&&, ||, ??) и выражения присваивания:

До сих пор в JavaScript есть следующие операторы присваивания:

=
Assignment operator.
/=
Division assignment.
*=
Multiplication assignment.
&&=
Logical AND assignment.
||=
Logical OR assignment.
??=
Logical nullish assignment.
**=
Exponentiation assignment.
%=
Remainder assignment.
+=
Addition assignment.
-=
Subtraction assignment.
<<=
Left shift assignment.
>>=
Right shift assignment.
>>>=
Unsigned right shift assignment.
&=
Bitwise AND assignment.
^=
Bitwise XOR assignment.
|=
Bitwise OR assignment.
Destructuring assignment operators:
[a, b] = [10, 20]
{a, b} = {a:10, b:20}

И с этим предложением мы объединим логические операторы и выражения присваивания:

a ||= b
//Equivalent to : a || (a = b), only assigns if a is Falsy.
a &&= b
//Equivalent to: a && (a = b), only assigns if a is Truthy.
a ??= b
//Equivalent to: a ?? (a = b), only assigns if a is Nullish.

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

Цифровые разделители (Christophe Porteneuve) расширяют существующий NumericLiteral, позволяя использовать символ-разделитель между цифрами.

Благодаря этой функции можно легко сделать числовые литералы более удобочитаемыми, создав визуальное разделение между группами цифр.

Например:

const money = 1000000000000;

Вышеупомянутый числовой литерал сложно читать, но мы можем использовать подчеркивания в качестве разделителей, чтобы облегчить чтение:

const money = 1_000_000_000_000;

Хорошо, теперь стало легче читать переменную "деньги".

Числовые разделители могут использоваться в разных позициях:

const money = 1_000_000.123_456;

Кроме того, числовые разделители доступны в восьмеричных целочисленных литералах.

const octal = 0o123_123;

Заключение

JavaScript постоянно добавляет новые функции. В этой статье мы рассмотрели некоторые из этих функций, которые, скорее всего, будут включены в JavaScript ES2021 (ES12).

Спасибо, что прочитали меня. Заботиться!

Больше:

использованная литература