Intl.NumberFormat выступает центральным инструментом
форматирования числовых значений в зависимости от локали, культурных
правил и контекста отображения. Его основная задача — преобразование
числовых данных в человекочитаемое представление с учётом языка,
региона, системы счисления, валютных обозначений и правил группировки
разрядов.
Ключевая особенность заключается в том, что форматирование не является строковой операцией в классическом смысле. Возвращаемый результат зависит от набора параметров локали и опций:
При этом Intl.NumberFormat становится не конечной
точкой, а компонентом, который эффективно комбинируется с другими API
международализации.
Одной из ключевых задач локализации является корректное согласование
числительных с существительными. Intl.PluralRules позволяет
определять грамматическую форму числа в зависимости от локали.
Комбинирование с Intl.NumberFormat реализуется через
разделение ответственности:
Intl.NumberFormat отвечает за визуальное представление
числаIntl.PluralRules отвечает за грамматическую
категориюПример логики композиции:
получить категорию числа:
one, few, many,
otherвыбрать правильную форму слова
отформатировать число для вывода
const nf = new Intl.NumberFormat('ru-RU');
const pr = new Intl.PluralRules('ru-RU');
const forms = {
one: 'товар',
few: 'товара',
many: 'товаров',
other: 'товара'
};
function formatCount(value) {
const category = pr.select(value);
const number = nf.format(value);
return `${number} ${forms[category]}`;
}
Такая схема отделяет числовое представление от грамматики, что критично для масштабируемых мультиязычных интерфейсов.
В реальных интерфейсах числа редко существуют изолированно. Часто они комбинируются с датами, создавая составные строки: статистика, отчёты, финансовые записи.
Intl.DateTimeFormat и Intl.NumberFormat
работают как независимые форматеры, но объединяются на уровне композиции
строк.
Пример структуры:
Intl.DateTimeFormatIntl.NumberFormatconst nf = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD'
});
const df = new Intl.DateTimeFormat('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric'
});
function formatReport(date, amount) {
return `${df.format(date)} — ${nf.format(amount)}`;
}
Такая композиция позволяет сохранять независимость форматирования каждого типа данных, избегая дублирования локализационной логики.
Метод formatToParts возвращает структурированное
представление числа, разбитое на семантические компоненты:
Это позволяет строить сложные UI-структуры, где каждая часть числа управляется отдельно.
const nf = new Intl.NumberFormat('de-DE', {
style: 'currency',
currency: 'EUR'
});
const parts = nf.formatToParts(12345.67);
Результат представляет собой массив объектов:
[
{ type: 'integer', value: '12' },
{ type: 'group', value: '.' },
{ type: 'integer', value: '345' },
{ type: 'decimal', value: ',' },
{ type: 'fraction', value: '67' },
{ type: 'literal', value: ' ' },
{ type: 'currency', value: '€' }
]
Такой формат позволяет:
function renderNumber(parts) {
return parts.map(part => {
if (part.type === 'currency') {
return `<span class="currency">${part.value}</span>`;
}
if (part.type === 'fraction') {
return `<span class="fraction">${part.value}</span>`;
}
return part.value;
}).join('');
}
В сложных интерфейсах форматирование чисел редко является изолированным действием. Оно включается в шаблоны сообщений, где числа являются переменными.
Комбинация строится следующим образом:
Intl.NumberFormat формирует локализованное числоconst nf = new Intl.NumberFormat('ru-RU');
function renderMessage(userCount, activeCount) {
return `Пользователей: ${nf.format(userCount)}, активных: ${nf.format(activeCount)}`;
}
При масштабировании используется слой функций:
Intl.NumberFormatПри проектировании UI-компонентов числовые значения часто используются в разных контекстах:
Комбинирование происходит через единый слой форматирования:
Intl.NumberFormatIntl.PluralRulesIntl.DateTimeFormatПример структуры компонента:
const formatters = {
number: new Intl.NumberFormat('fr-FR'),
currency: new Intl.NumberFormat('fr-FR', {
style: 'currency',
currency: 'EUR'
})
};
function renderRow(item) {
return {
title: item.name,
price: formatters.currency.format(item.price),
count: formatters.number.format(item.count)
};
}
Такой подход формирует единый контракт форматирования данных вне зависимости от слоя отображения.
Создание экземпляра Intl.NumberFormat является
относительно дорогой операцией, особенно при частом рендеринге
интерфейсов.
Ключевые принципы оптимизации:
const cache = new Map();
function getNumberFormatter(locale, options) {
const key = JSON.stringify({ locale, options });
if (!cache.has(key)) {
cache.set(key, new Intl.NumberFormat(locale, options));
}
return cache.get(key);
}
Такой подход снижает накладные расходы при массовом форматировании.
При серверном рендеринге возникает задача согласования локали между сервером и клиентом.
Особенности:
Использование Intl.NumberFormat на сервере позволяет
формировать уже локализованный HTML до отправки клиенту, снижая нагрузку
на браузер.
Intl.NumberFormat поддерживает разные режимы:
currencyunitpercentcompactКомбинирование происходит через единый интерфейс форматирования, где различие определяется только конфигурацией.
const compact = new Intl.NumberFormat('en-US', {
notation: 'compact'
});
const percent = new Intl.NumberFormat('en-US', {
style: 'percent'
});
Компактная форма часто используется в аналитических панелях:
Это форматирование может комбинироваться с formatToParts
для выделения суффиксов и стилизации.
При сложной композиции форматеров возникают особенности:
Intl.NumberFormat инкапсулирует эти различия, но при
комбинировании через строки важно сохранять результат форматтера без
повторной обработки.
В масштабируемых системах Intl.NumberFormat обычно
становится частью более широкого слоя:
Композиция строится таким образом, что форматирование чисел становится атомарной операцией внутри более сложной системы интернационализации, где каждое API отвечает за узкий аспект локализации и не пересекается с другими по ответственности.