Ничего умопомрачительного, если честно

Многие из нас думали, что с выпуском 10-й версии спецификации в ECMAScript будут внесены серьезные улучшения.

Однако они нет. Все следующие предложения по-прежнему находятся на этапе 3:

  1. BigInt
  2. Верхний уровень await
  3. Promise.allSettled()
  4. Средства доступа к классам, поля и модификаторы конфиденциальности

И много других интересных.

Вместо этого редакторы решили не торопиться, и поэтому 10-я версия спецификации представляет нам лишь несколько довольно полезных новых методов и улучшений синтаксиса/семантики. Давайте погрузимся!

Array.prototype.flat()

Сглаживает предоставленный массив, как следует из названия

[[["nested", ["arrays"]]], [["inside"]], [[["the"]]], ["array"]]
->
["nested", "arrays", "inside", "the", "array"]

Метод не мутирует

let a = [[1]];
a.flat(); // -> [1]
a; // -> [[1]]

Он принимает depth в качестве единственного аргумента. Значение по умолчанию depth равно 1. Значение undefined также считается равным 1. Все остальные значения преобразуются в целое число (которое в большинстве случаев будет оцениваться как 0)

let a = [[1]];
a.flat(1); // -> [1]
a.flat(undefined); // -> [1]
a.flat("1"); // -> [1]
let b = [[[2]]];
b.flat(1); // -> [[2]]
b.flat(2); // -> [2]
b.flat("2"); // -> [2]
b.flat(100); // -> [2]

В новом методе flat хорошо то, что он наконец-то представлен. Больше нет необходимости реализовывать его вручную. Плохо то, что с ним нет возможности обрабатывать массивы неизвестной глубины. Вы должны либо использовать что-то вроде Number.MAX_SAFE_INTEGER, либо рекурсивно вызывать метод каждый раз, проверяя, содержит ли целевой массив вложенные массивы внутри себя.

Array.prototype.flatMap()

Хотя название немного сбивает с толку. Кажется, что он сначала сглаживает входной массив, а затем отображает его. Но на самом деле он работает с точностью до наоборот: он сначала отображает массив как есть, а только потом сглаживает его и возвращает сбитую версию сопоставленного массива.

let a = [[1], [[2]], [[[3]]]];
a.flatMap((item, i) => item + i); // -> ["10", "21", "32"]
// but not [1, 3, 5] nor [1, "21", "32"] as you might've expected at first

Если предоставленный обратный вызов не может быть вызван (то есть не является функцией), будет выдана ошибка TypeError (то же самое относится и к функции Array.prototype.map()).

Невозможно указать, до какой глубины вам нужно сгладить массив. depth всегда 1.

Object.fromEntries

Object.entries возвращает массив массивов, состоящий из пар ключ-значение предоставленного объекта

let a = {
  a: 1,
  b: 2
};
Object.entries(a); // -> [["a", 1], ["b", 2]]

Object.fromEntries по сути противоположен Object.entries — он создает объект из этих пар ключ-значение (записей)

let a = [
  ["a", 1],
  ["b", 2]
];
Object.fromEntries(a); // -> {a: 1, b: 2}

Сочетание этих двух методов может стать весьма полезным для копирования объектов.

let a = {
  a: 1,
  b: 2
};
Object.fromEntries(Object.entries(a)) === a; // -> false
// a new object is created

String.prototype.trimStart() и String.prototype.trimEnd()

… которые ранее были известны как trimLeft и trimRight соответственно (хотя эти 2 были нестандартными и теперь добавлены в спецификацию с учетом обратной совместимости).

Как следует из их названий, String.prototype.trimStart() обрезает начало целевой строки, а String.prototype.trimEnd() обрезает конец целевой строки.

"   Hello   ".trim(); // -> "Hello"
"   Hello   ".trimStart(); // -> "Hello   "
"   Hello   ".trimEnd(); // -> "   Hello"

Есть и другие незначительные улучшения синтаксиса и семантики.

Теперь допустимо опускать параметры привязки catch.

try {
 throw new Error();
} catch { // notice the absence of `()`
 console.error(“An unknown error occurred”);
}

Array.prototype.sort() стал «стабильной сортировкой», что означает, что если функция сравнения вернет 0, исходные элементы останутся нетронутыми. Ранее поведение определялось реализациями.

Метод JSON.stringify теперь всегда возвращает текст в кодировке UTF-8 независимо от того, в какой кодировке он вводил.

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