ECMAScript — это стандарт JavaScript, разработанный Ecma International. Каждый июнь, начиная с 2015 года, выпускается новая основная версия, и этот год ничем не отличался от представленных 6 новых захватывающих методов. Мы подробно рассмотрим каждую из этих новых функций, а также то, что уже предложено на 2024 год. Чтобы освежить вашу память, сначала давайте подумаем о том, что было добавлено за последние годы:

Краткое изложение ES2023

Поиск массива из последнего

При поиске значения в массиве обычно используется метод .find(). Этот метод возвращает первый элемент в массиве, который удовлетворяет предоставленной функции тестирования. Если нам нужен индекс значения, мы можем использовать .findIndex(). Проблема с этими методами заключается в том, что они перебирают массив слева направо. Однако, если вы знаете, что искомое значение, скорее всего, находится в конце массива, для его получения потребуется много итераций.

Обходным путем для этого было бы перевернуть массив, но это означает: 1) ненужную мутацию (путем реверсирования массива) или 2) ненужное копирование массива (чтобы избежать мутации). В дополнение к этому, для .findIndex() вам потребуется выполнить сложный пересчет индекса, поскольку обращение массива изменит все исходные индексы.

Здесь на помощь приходит ES2023 с двумя новыми методами: .findLast() и .findLastIndex(). Оба эти метода делают то, о чем говорят их названия — они ищут массив справа налево, избегая ненужных обходных путей, описанных выше.

//we want to find the value 82 towards the end of the list
const numbers = [42,13,7,21,82,100]; 

//Before the proposal

//find 
[...numbers].reverse().find(n => n.value === 82); //82 iterates left to right

//findIndex
numbers.length - 1 - [...numbers].reverse().findIndex(n => n.value === 82); //4 
numbers.length - 1 - [...numbers].reverse().findIndex(n => n.value === 98); //should be -1, but 6

//After the proposal

//find
numbers.findLast(n => n.value === 82); //82 iterates right to left

//findIndex
numbers.findLastIndex(n => n.value === 82);  //82
numbers.findLastIndex(n => n.value === 98);  //-1

Грамматика Hashbang

Hashbangs #! — это последовательность символов в начале сценария на основе Unix, которая определяет, с каким интерпретатором будет выполняться сценарий. Это позволяет выполнять скрипты JavaScript как автономные исполняемые файлы. До сих пор ожидалось, что среда выполнения JavaScript будет обрабатывать синтаксис Hashbang, и если ничего не получится, он будет просто проигнорирован. Однако формального стандарта для обработки этого синтаксиса не существовало, и это то, что предлагает Брэдли Фариас в ES2023.

#!/usr/bin/env node
console.log('Hello, World!');

Символы как ключи WeakMap

Ранее WeakMaps поддерживали только объекты в качестве ключей, несмотря на то, что символы также имели особенность быть уникальными и невоспроизводимыми. ES2023 исправляет это, позволяя использовать символы в качестве ключей, обеспечивая большую гибкость в использовании преимуществ оптимизации памяти WeakMaps.

const weakMap = new WeakMap();
const key = Symbol("key1");
WeakMap.set(key, "Welcome Symbols to WeakMap !");
console.log(weakMap.get(key)); // Welcome Symbols to WeakMap !

Изменить массив путем копирования

Методы массива JavaScript .reverse(), .sort() и .splice() изменяют исходный массив. В этом предложении представлены три эквивалентных метода (.toReversed(), .toSorted() и .toSpliced()), которые вместо этого возвращают копию, оставляя исходный массив нетронутым. Кроме того, был введен метод .with(index,value), который возвращает копию массива с заменой значения по указанному индексу. Эти дополнения помогают расширить универсальность манипуляций с массивами, ознакомьтесь с примерами ниже:

// toReversed() returns a copy of the reversed array leaving original untouched
const sequence = [1,2,3,4];
const reversed = original.toReversed(); 
console.log(reversed); // [4,3,2,1]
console.log(sequence); // [1,2,3,4]

//toSorted() returns a copy of the sorted array leaving original untouched
const unsorted = [1,3,4,2];
const sorted = unsorted.toSorted();
console.log(sorted); // [1,2,3,4]
console.log(unsorted); // [1,3,4,2]

//toSpliced() returns spliced copy of array leaving original untouched
const original = [1,4];
const spliced = original.toSpliced();
console.log(spliced); //[1,2,3,4]
console.log(original); // [1,4]

//with() returns a copy of the altered array leaving original untouched
const unaltered = [1,2,4];
const altered = unaltered.with(2,3);
console.log(altered); // [1,2,3]
console.log(unaltered); // [1,2,4]

Что нас ждет на ES2024?

На данный момент три предложения находятся в стадии завершения (этап 4) и находятся на пути к включению в моментальный снимок ECMAScript 2024:

Правильно сформированные строки Unicode

Одиночный суррогат описывается как строка, содержащая символы Unicode в диапазоне от 0xD800–0xDBFF до 0xDC00–0xDFFF. Строка неправильно сформирована, если она содержит один суррогат. В этом предложении представлены два новых метода, которые помогают работать со строками неправильного формата:

String.prototype.isWellFormed

Возвращает true, если строка не содержит один суррогат. Это особенно полезно в сценарии для интерфейсов между JavaScript/веб-APIS.

const str1 = "ab\uD800";
const str2 = "abc";
console.log(str1.isWellFormed()); //false
console.log(str2.isWellFormed()); //true

String.prototype.toWellFormed

Возвращает строку, в которой все одиночные суррогаты строки заменены символом замены Юникода U+FFFD. Это имитирует операцию, уже выполненную в не-ECMAScript APIS.

const str1 = "ab\uD800";
const str2 = "abc";
console.log(str1.toWellFormed()); //ab�
console.log(str2.toWellFormed()); // abc

Флаг регулярного выражения v с установленным обозначением и свойствами строк

Регулярные выражения являются одним из самых полезных инструментов в JavaScript и поддерживаются с 1999 года. С тех пор они постоянно улучшались, и похоже, что ES2024 получит больше улучшений. Похоже, что вводится режим unicodeSets, который включается с помощью флага v. Примечательные функции этого флага включают свойства строк Unicode, установленную нотацию и улучшенное сопоставление без учета регистра для классов символов с отрицанием. Подробные примеры новых функций см. в предложении Документация.

Atomics.waitAsync

Этот метод находился в стадии разработки в течение довольно долгого времени, но на заседании TC39 в мае 2023 года он достиг статуса 4. Это статический метод, который асинхронно ожидает в общей области памяти и возвращает обещание. В отличие от Atomics.wait(), он не блокирует и может использоваться в основном потоке.

const arrayBuffer = new SharedArrayBuffer(1024);
const arr = new Int32Array(arrayBuffer);

//This will wait for position 0 on the int32 array and expect a result of 0, 
//waiting for 500 ms
Atomics.waitAsync(arr, 0 , 0 , 500);
// { async: true, value: Promise {<pending>}}

//the notify method awakes the array and the promise is fulfilled
Atomics.notify(arr, 0);
// { async: true, value: Promise {<fulfilled>: 'ok'} }

И это завершение…

Ecma International стремится постоянно развивать JavaScript, и этот год не стал исключением. Имея уже три предложения по этапу 4, мы с нетерпением ждем того, что будет дальше. Дополнительные примеры и подробное описание новых функций, описанных в этом блоге, можно найти в репозитории предложений tc39.

Об авторе:
Кайл Карсон (Kyle Carson) является разработчиком Full Stack Java здесь, в версии 1.