`Intl.ListFormat`
Современные веб-приложения часто используют списки, состоящие из динамических данных. Например, приложение для просмотра фотографий может отображать что-то вроде:
Эта фотография включает Аду, Эдит и Грейс.
Текстовая игра может иметь другой вид списка:
Выберите свою суперсилу: невидимость, психокинез или эмпатию.
Так как у каждого языка есть свои собственные правила форматирования списков и слова, реализация локализованного форматирования списка является нетривиальной задачей. Это требует не только списка всех слов (например, «и» или «или» в приведенных выше примерах) для каждого поддерживаемого языка — к тому же нужно описать точные правила форматирования для всех этих языков! Unicode CLDR предоставляет эти данные, но чтобы использовать их в JavaScript, их нужно интегрировать и включить в библиотеку. Это, к сожалению, увеличивает размер пакета для таких библиотек, что негативно сказывается на времени загрузки, стоимости обработки/компиляции и потреблении памяти.
Совершенно новый API Intl.ListFormat
перекладывает эту задачу на JavaScript-движок, который может предоставлять данные локализации и делать их доступными непосредственно разработчикам JavaScript. Intl.ListFormat
позволяет локализованно форматировать списки без ущерба для производительности.
Примеры использования
Следующий пример показывает, как создать форматтер списка для соединений, используя английский язык:
const lf = new Intl.ListFormat('en');
lf.format(['Frank']);
// → 'Frank'
lf.format(['Frank', 'Christine']);
// → 'Frank and Christine'
lf.format(['Frank', 'Christine', 'Flora']);
// → 'Frank, Christine, and Flora'
lf.format(['Frank', 'Christine', 'Flora', 'Harrison']);
// → 'Frank, Christine, Flora, and Harrison'
Используя параметр options
, также можно работать с дизъюнкциями («или» на английском):
const lf = new Intl.ListFormat('en', { type: 'disjunction' });
lf.format(['Frank']);
// → 'Frank'
lf.format(['Frank', 'Christine']);
// → 'Frank or Christine'
lf.format(['Frank', 'Christine', 'Flora']);
// → 'Frank, Christine, or Flora'
lf.format(['Frank', 'Christine', 'Flora', 'Harrison']);
// → 'Frank, Christine, Flora, or Harrison'
Вот пример использования другого языка (китайского, с языковым кодом zh
):
const lf = new Intl.ListFormat('zh');
lf.format(['永鋒']);
// → '永鋒'
lf.format(['永鋒', '新宇']);
// → '永鋒和新宇'
lf.format(['永鋒', '新宇', '芳遠']);
// → '永鋒、新宇和芳遠'
lf.format(['永鋒', '新宇', '芳遠', '澤遠']);
// → '永鋒、新宇、芳遠和澤遠'
Параметр options
позволяет более продвинутое использование. Вот обзор различных опций и их комбинаций, а также их соответствие шаблонам списков, определенным UTS#35:
Тип | Опции | Описание | Примеры |
---|---|---|---|
стандартный (или нет типа) | {} (по умолчанию) | Типичный список с «и» для произвольных заполнителей | 'January, February, and March' |
или | { type: 'disjunction' } | Типичный список с «или» для произвольных заполнителей | 'January, February, or March' |
единица | { type: 'unit' } | Список, подходящий для широких единиц измерения | '3 feet, 7 inches' |
единица-короткий | { type: 'unit', style: 'short' } | Список, подходящий для коротких единиц измерения | '3 ft, 7 in' |
единица-узкий | { type: 'unit', style: 'narrow' } | Список, подходящий для узких единиц измерения, где пространство экрана строго ограничено | '3′ 7″' |
Учтите, что во многих языках (например, английском) может не быть различий между многими из этих списков. В других же изменение пробелов, длины или наличия соединительного слова, а также разделителей может быть явным.
Заключение
По мере того как API Intl.ListFormat
становится все более доступным, вы обнаружите, что библиотеки отказываются от зависимости от жестко закодированных баз данных CLDR в пользу встроенной функции форматирования списков, тем самым улучшая производительность времени загрузки, времени разбора и компиляции, производительность во время выполнения и использование памяти.