Ура-ура! Сразу несколько приятных и полезных фич перешли на стадию завершения, а значит, в 2020 году нас ждет много радостей. Наконец-то в стандарте появятся долгожданные опциональные последовательности и динамический импорт. Оставим их на сладкое, а сначала посмотрим, что еще приготовил разработчикам TC39.
Если вы не можете удержаться, загляните в репозиторий пропозалов на страничку Finished Proposals. Там вы найдете полный список предложений, достигших стадии 4.
String.prototype.matchAll
Представим, строка сопоставляется с подстрокой или регулярным выражением. Чтобы найти все совпадения, придется потрудиться. Ведь метод String.prototype.match для обычной регулярки возвращает информацию только о первом совпадении:
А для глобального регулярного выражения возвращается малоинформативный массив:
В прототипе RegExp есть подходящий метод exec. Для обычного выражения он работает так же, как String.prototype.match
– ничего интересного:
С глобальными регулярками уже можно работать:
Каждый вызов возвращает следующее совпадение, а когда строка кончится – null
. Чтобы перебрать длинные строки, можно воспользоваться циклом while
. Позиция для начала поиска хранится в свойстве lastIndex
объекта регулярного выражения. Это не так уж очевидно, правда?
На смену этому подходу пришел удобный и интуитивно понятный метод String.prototype.matchAll. Он возвращает итератор:
Вызов next()
выводит каждое следующее значение:
Но можно воспользоваться уже имеющимися благами ES6 и сделать вот так:
Одной строчкой кода мы собрали полную информацию обо всех совпадениях в строке.
BigInt
До появления нового типа данных BigInt приходилось пользоваться типом Number. Самое большое число, которое можно было точно представить в JavaScript, равнялось 2⁵³-1 (константа Number.MAX_SAFE_INTEGER
).
Теперь не обязательно ограничивать себя этой ничтожной величиной. Расправьте крылья и воспарите в пространстве по-настоящему больших чисел.
Чтобы создать значение с типом BigInt, добавьте к числу n
или воспользуйтесь встроенной функцией BigInt()
.
- Значение BigInt не может быть строго равно значению Number, но выражение
2n == 2
истинно. - При делении результат всегда будет округляться до нуля (
4n / 10n = 0n
). - Нельзя смешивать в одной операции BigInt и Number, так как неявное преобразование между этими типами не происходит (
4n + 2
).
globalThis
Получение доступа к глобальным объектам – это вечная головная боль в JavaScript. В каждой среде выполнения свои особенности, свой синтаксис, который нужно знать, чтобы ваш код можно было свободно портировать.
Обычно мы выходили из этого положения, создавая функцию getGlobal()
, внутри которой перебирали все возможные варианты:
После того как появился globalThis
, можно с чистой совестью забыть об этом зоопарке. Например, в браузере в объекте globalThis
вы найдете знакомый window
:
Promise.allSettled
Если вам требуется дождаться выполнения сразу нескольких промисов, вы, конечно, обратитесь к методу Promise.all()
. Но он принимает только успешно выполненные «обещания». Если где-то появится ошибка, продолжить работу не получится.
Новому методу Promise.allSettled() наплевать, как завершились ваши промисы – главное, что они отработали.
Динамический импорт
Еще одна новая фича JavaScript, которой вы наверняка будете пользоваться – динамический импорт. Теперь модули можно загружать прямо в рантайме – в зависимости от некоторого условия или просто отложенно, чтобы не загружать клиент. Достаточно вызвать функцию import()
, передать указатель на нужный модуль и получить ответный промис.
Или даже пользоваться шаблонными строками, чтобы динамически указать имя модуля:
Nullish coalescing
У вас есть некоторый объект. Нужно получить и вернуть значение одного из его свойств, если оно не равно null
или undefined
. В обратном случае возвратить значение по умолчанию. Как бы вы решили эту задачу?
Наверняка вы обратитесь к логическому оператору ИЛИ (||
):
Но есть небольшая проблема. Если в свойстве лежит пустая строка или ноль, мы все равно получим в ответе правую часть выражения ('Response'
), так как это ложные значения:
Оператор Nullish coalescing, или оператор объединения с null
, позволяет решить эту задачу. Если свойство равно null
или undefined
, то вернется правое значение. Во всех остальных случаях – левое. Независимо от того, истинное оно или ложное.
Опциональные последовательности
Если вы хоть раз пытались получить глубоко вложенное свойство объекта, то знаете, какая это мука. На каждом уровне поджидает ошибка – ведь искомого свойства может и не быть. Приходится действовать пошагово, доставать всю цепочку свойств по очереди, одно за другим. Это ужасно утомляет и нервирует.
Нас спасут опциональные последовательности (англ. Optional Chaining). Достаточно поставить рядом с потенциально несуществующим свойством оператор ?.
(вопросительный знак как символ сомнения и точка для стандартного доступа к свойству объекта).
Результат тот же, а запись короче и понятнее!
Вы тоже не можете дождаться?
Если у вас чешутся руки использовать эти приятные возможности в работе, не ограничивайте себя! Многие из них уже воплощены в движках, и практически для всех есть плагины babel. Наслаждайтесь ;)
Комментарии