Подписывайтесь на мой твиттер, там всегда что-нибудь интересное!

Интересные нововведения в JavaScript ES2021

В этой статье вы узнаете про интересные нововведения в JavaScript, которые ожидают нас в 2021 году. Не все конечно, но тут собраны и описаны самые интересные из них.

Перевод JavaScript ES2021 Exciting Features

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

Новый функционал, каждый год добавляемый в JS, проходит через четыре стадии рассмотрения. В этой статье мы обсудим тот функционал, который уже находится на 4-й стадии, то есть на последней и который уже был успешно добавлен в Google Chrome V8.

Функционал, который мы будем обсуждать в этой статье:

String.prototype.replaceAll

Promise.any

Логические операторы и выражения присваивания

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

Intl.ListFormat

dateStyle и timeStyle для Intl.DateTimeFormat

String.prototype.replaceAll

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

Предложенный в ES2020 метод replaceAll() отдаёт новую строку, где все подходящие символы будут заменены на другие. Это могут быть строки или регулярные выражения, а заменять можно будет на строку или функцию, которая будет отрабатывать при каждом совпадении.

let str = 'I use linux, I love linux'
str = str.replaceAll('linux', 'windows');

console.log(str)

/****  Output  ****/
// I use windows, I love windows

Promise.any

В ES2020 нам представят метод Promise.any(), который резко останавливается и сразу отдаёт значение, как только выполнится первый промис из списка выполняемых промисов. Если выполнение всех промисов закончится неудачей, то будет выдана ошибка.

Этот метод конечно же отличается от Promise.race() тем, что последний останавливается и выдает промис вне зависимости от результата его выполнения.

Пример 1а: Несмотря на то, что неудачно завершившийся промис заканчивает работу раньше, чем успешно завершившийся. Promise.any() отдаст первый из успешно завершившихся.

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(`Result: ${value}`))
.catch (err => console.log(err))

/****  Output  ****/
// Result: Second

Пример 1б: Когда все промисы неудачно завершаются, то выдает AggregatorError.

Promise.any([
  Promise.reject('Error 1'),
  Promise.reject('Error 2'),
  Promise.reject('Error 3')
])
.then(value => console.log(`Result: ${value}`))
.catch (err => console.log(err))

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

Логические операторы и выражения присваивания

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

// Выражение присвивания
let num = 5
num+=10
console.log(num) // 15

// Логический оператор
let num1 = 6
let num2 = 3
console.log(num1 === 6 && num2 === 2) // false
console.log(num1 === 6 || num2 === 2) // true

С помощью нового функционала мы сможем комбинировать логические операторы и выражения присваивания. Ниже вы увидите несколько примеров с &&, || и ??:

Логический оператор назначения с &&

Тут мы выставляем значение левосторонней переменной только в том случае, если правая имеет значение true.

let num1 = 5
let num2 = 10

num1 &&= num2

console.log(num1) // 10

// можно записать как
// 1. num1 && (num1 = num2)
// 2. if (num1) num1 = num2

Логический оператор назначения с ||

Тут мы выставляем значение num1 на левую переменную только в том случае, если последняя будет false.

let num1
let num2 = 10

num1 ||= num2

console.log(num1) // 10

// можно записать как
// 1. num1 || (num1 = num2)
// 2. if (!num1) num1 = num2

Логический оператор назначения с ??

В ES2020 был представлен Nullish Coalescing оператор, который можно совмещать с оператором назначения. Он назначает правую переменную левой переменной только в случае, если последняя имеет значение undefined или null.

let num1
let num2 = 10

num1 ??= num2
console.log(num1) // 10

num1 = false
num1 ??= num2
console.log(num1) // false

// можно записать как
// num1 ?? (num1 = num2)

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

С приходом числовых разделителей станет куда проще читать и воспринимать числовые значения, применяя _(нижнее подчеркивание), раздавая разделители группам цифр. Для примера:

let number = 100_000 

console.log(number)

/****  Output  ****/
// 100000

Intl.ListFormat

Этот объект принимает два параметра, каждый из которых является опциональным. Первый это заданный язык(локаль), а второй это объект с параметрами у которых есть два свойства — стиль и тип.

new Intl.ListFormat([locales[, options]])

В Intl.ListFormat есть метод под названием format(), который получает массив как аргумент и форматирует его разными способами в зависимости от языка.

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

const arr = ['Pen', 'Pencil', 'Paper']

let obj = new Intl.ListFormat('en', { style: 'short', type: 'conjunction' })
console.log(obj.format(arr)) 

/****  Output  ****/
// Pen, Pencil, & Paper


obj = new Intl.ListFormat('en', { style: 'long', type: 'conjunction' })
console.log(obj.format(arr)) 

/****  Output  ****/
// Pen, Pencil, and Paper


obj = new Intl.ListFormat('en', { style: 'narrow', type: 'conjunction' })
console.log(obj.format(arr)) 

/****  Output  ****/
// Pen, Pencil, Paper


// Итальянский
obj = new Intl.ListFormat('it', { style: 'short', type: 'conjunction' })
console.log(obj.format(arr)) 

/****  Output  ****/
// Pen, Pencil e Paper


// Немецкий
obj = new Intl.ListFormat('de', { style: 'long', type: 'conjunction' })
console.log(obj.format(arr)) 

/****  Output  ****/
// Pen, Pencil und Paper

dataStyle и timeStyle опции для Intl.DateTimeFormat

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

// Только время в коротком формате
let o = new Intl.DateTimeFormat('en' , { timeStyle: 'short' })
console.log(o.format(Date.now()))
// 11:27 PM


// Только время в обычном формате
o = new Intl.DateTimeFormat('en' , { timeStyle: 'medium'})
console.log(o.format(Date.now()))
// 11:27:57 PM


// Время в расширенном формате
o = new Intl.DateTimeFormat('en' , { timeStyle: 'long' })
console.log(o.format(Date.now()))
// 11:27:57 PM GMT+11


// Только дата в сокращенном формате
o = new Intl.DateTimeFormat('en' , { dateStyle: 'short'})
console.log(o.format(Date.now()))
// 10/6/20


// Только дата в обычном формате
o = new Intl.DateTimeFormat('en' , { dateStyle: 'medium'})
console.log(o.format(Date.now()))
// Oct 6, 2020


// Только дата в расширенном формате
o = new Intl.DateTimeFormat('en' , { dateStyle: 'long'})
console.log(o.format(Date.now()))
// October 6, 2020

dateStyle и timeStyle используются вместе с разными лингвистическими тегами, как показано на примере ниже:

let abc

// Английский
abc = new Intl.DateTimeFormat('en' , { timeStyle: 'short', dateStyle: 'long'})
console.log(abc.format(Date.now()))
// October 6, 2020 at 11:40 PM


// Итальянский
abc = new Intl.DateTimeFormat('it' , { timeStyle: 'short', dateStyle: 'long'})
console.log(abc.format(Date.now()))
// 6 ottobre 2020 23:40


// Немецкий
abc = new Intl.DateTimeFormat('de' , { timeStyle: 'short', dateStyle: 'long'})
console.log(abc.format(Date.now()))
// 6. Oktober 2020 um 23:40