Объект Intl.ListFormat предназначен для локализованного
форматирования списков значений с учётом правил языка: союзов,
пунктуации и грамматики. Его задача — заменить ручную конкатенацию строк
(arr.join(", ")) корректными языковыми конструкциями вроде
«A, B и C» или «A, B или C», учитывая особенности конкретной локали.
Базовый принцип работы заключается в том, что форматирование списка делегируется движку интернационализации, который применяет правила выбранного языка для соединения элементов.
Конструктор принимает два аргумента:
locales — строка или массив локалейoptions — объект конфигурации форматированияconst formatter = new Intl.ListFormat('ru', {
style: 'long',
type: 'conjunction'
});
Если локаль не указана, используется системная по умолчанию.
Параметр type определяет семантику соединения элементов
списка.
Используется для перечислений с союзом «и»:
const f = new Intl.ListFormat('ru', { type: 'conjunction' });
f.format(['яблоки', 'бананы', 'груши']);
// "яблоки, бананы и груши"
Этот режим является наиболее распространённым, так как отражает логическое объединение элементов.
Используется для альтернатив, где применяется «или»:
const f = new Intl.ListFormat('ru', { type: 'disjunction' });
f.format(['JavaScript', 'TypeScript', 'Dart']);
// "JavaScript, TypeScript или Dart"
Подходит для сценариев выбора или условий.
Применяется для измерений, единиц и технических перечислений:
const f = new Intl.ListFormat('ru', { type: 'unit' });
f.format(['5 кг', '200 г', '30 мг']);
// "5 кг, 200 г, 30 мг"
Особенность режима заключается в том, что язык может использовать менее «разговорные» формы соединения.
Параметр style управляет степенью подробности и
формальностью результата.
Полная форма с традиционными союзами:
const f = new Intl.ListFormat('ru', {
style: 'long',
type: 'conjunction'
});
f.format(['HTML', 'CSS', 'JavaScript']);
// "HTML, CSS и JavaScript"
Сокращённый формат, зависящий от локали:
const f = new Intl.ListFormat('en', {
style: 'short',
type: 'conjunction'
});
f.format(['apples', 'bananas', 'oranges']);
// "apples, bananas & oranges"
В некоторых языках разница между long и
short минимальна, но в английском она может проявляться
через символы вроде &.
Максимально компактный формат:
const f = new Intl.ListFormat('en', {
style: 'narrow',
type: 'conjunction'
});
f.format(['A', 'B', 'C']);
// "A, B, C"
Используется в интерфейсах с ограниченным пространством.
Локализация влияет не только на союзы, но и на порядок элементов, использование запятых и пробелов.
const ru = new Intl.ListFormat('ru', { type: 'conjunction' });
const en = new Intl.ListFormat('en', { type: 'conjunction' });
const de = new Intl.ListFormat('de', { type: 'conjunction' });
const data = ['HTML', 'CSS', 'JS'];
ru.format(data);
en.format(data);
de.format(data);
Результаты будут отличаться не только словами «и»/«and»/«und», но и типографикой.
Основной метод преобразует массив в строку:
const formatter = new Intl.ListFormat('ru', {
style: 'long',
type: 'conjunction'
});
formatter.format(['Москва', 'Казань', 'Сочи']);
// "Москва, Казань и Сочи"
Если передаётся один элемент, он возвращается без изменений:
formatter.format(['Москва']);
// "Москва"
Пустой массив возвращает пустую строку.
Позволяет получить структуру результата в виде частей, а не одной строки.
const formatter = new Intl.ListFormat('ru', {
style: 'long',
type: 'conjunction'
});
formatter.formatToParts(['HTML', 'CSS', 'JS']);
Результат:
[
{ type: 'element', value: 'HTML' },
{ type: 'literal', value: ', ' },
{ type: 'element', value: 'CSS' },
{ type: 'literal', value: ' и ' },
{ type: 'element', value: 'JS' }
]
element — элемент спискаliteral — разделитель (запятая, союз и пробелы)Такой формат полезен для кастомного рендеринга интерфейсов, где требуется отдельно стилизовать элементы и разделители.
const formatter = new Intl.ListFormat('ru', { type: 'conjunction' });
const users = ['Анна', 'Иван', 'Мария'];
const text = formatter.format(users);
// "Анна, Иван и Мария"
const formatter = new Intl.ListFormat('en', { type: 'disjunction' });
const filters = ['red', 'green', 'blue'];
const label = formatter.format(filters);
// "red, green or blue"
const formatter = new Intl.ListFormat('ru', { type: 'unit' });
const values = ['10 см', '20 см', '30 см'];
formatter.format(values);
// "10 см, 20 см, 30 см"
Форматирование зависит от реализации движка JavaScript. Разные
браузеры могут иметь незначительные различия в деталях пунктуации,
особенно в режиме short и narrow.
При работе с большими массивами форматирование выполняется синхронно, но обычно не является узким местом производительности по сравнению с DOM-операциями.
Пустые или некорректные значения приводятся к строкам внутренним алгоритмом приведения типов.
Intl.ListFormat часто используется вместе с:
Intl.NumberFormat для числовых списковIntl.DateTimeFormat для перечисления датIntl.DisplayNames для локализованных названий стран и
языковconst list = new Intl.ListFormat('ru', { type: 'conjunction' });
const number = new Intl.NumberFormat('ru-RU');
const data = [number.format(1000), number.format(2000)];
list.format(data);
// "1 000 и 2 000"
Создание экземпляра форматтера дорогостоящее по сравнению с его использованием, поэтому обычно применяется переиспользование:
const formatter = new Intl.ListFormat('ru', { type: 'conjunction' });
function render(items) {
return formatter.format(items);
}
Это особенно важно при рендеринге списков в циклах или UI-фреймворках.