Форматирование чисел в разных языках и регионах опирается на различные правила разделения разрядов. В одних системах используется разделение тысяч через запятую, в других — через пробел, в третьих — применяется нестандартная схема группировки, например индийская (2–2–3 вместо классической 3–3–3).
Базовая задача Intl.NumberFormat заключается не только в
отображении числа, но и в применении локально корректной схемы
группировки разрядов, учитывающей региональные стандарты и правила
конкретной письменности.
Основной механизм:
new Intl.NumberFormat(locale).format(number)
Поведение группировки управляется внутренними правилами CLDR (Common Locale Data Repository), а не фиксированными настройками JavaScript.
Наиболее распространённая схема — группировка по три цифры справа налево.
Пример:
new Intl.NumberFormat("en-US").format(1234567890);
// 1,234,567,890
Для разных локалей результат отличается:
new Intl.NumberFormat("de-DE").format(1234567890);
// 1.234.567.890
new Intl.NumberFormat("fr-FR").format(1234567890);
// 1 234 567 890
Ключевой момент: разделитель и правила группировки определяются локалью, а не кодом.
Опция useGrouping контролирует включение или отключение
разделения разрядов.
new Intl.NumberFormat("en-US", { useGrouping: true }).format(1234567);
// 1,234,567
Отключение группировки:
new Intl.NumberFormat("en-US", { useGrouping: false }).format(1234567);
// 1234567
useGrouping может принимать дополнительные режимы в
современных реализациях:
"always" — всегда применять группировку"auto" — применять по умолчанию"min2" — группировать только при числе ≥ 10000 (зависит
от движка)"true" / "false" — логический режим
(устаревающий стиль)Поведение зависит от реализации ECMAScript-движка, но концепция остаётся одинаковой: контроль включения разрядных разделителей.
Некоторые регионы используют нестандартные схемы.
new Intl.NumberFormat("en-IN").format(123456789);
// 12,34,56,789
Группировка:
Эта система сохраняется даже при больших числах и применяется автоматически.
В китайской и японской нотации часто отсутствует привычная западная группировка:
new Intl.NumberFormat("zh-CN").format(123456789);
// 123,456,789 (или без разделителей в некоторых форматах)
В некоторых случаях локаль может предпочитать отсутствие разделителей при определённых стилях форматирования.
new Intl.NumberFormat("ar-EG").format(123456789);
// ١٢٣٬٤٥٦٬٧٨٩
Особенности:
Intl.NumberFormat позволяет не только получать строку,
но и структуру компонентов.
new Intl.NumberFormat("en-US").formatToParts(1234567);
Результат:
[
{ type: "integer", value: "1" },
{ type: "group", value: "," },
{ type: "integer", value: "234" },
{ type: "group", value: "," },
{ type: "integer", value: "567" }
]
Типы частей:
integer — числовые сегментыgroup — разделитель разрядовdecimal — десятичный разделительfraction — дробная частьliteral — служебные символыЭтот механизм позволяет полностью контролировать отображение чисел без изменения локальной логики форматирования.
Хотя Intl API не предоставляет прямой настройки символа разделителя,
formatToParts позволяет реконструировать строку:
const formatter = new Intl.NumberFormat("en-US");
const parts = formatter.formatToParts(1234567);
const custom = parts
.map(p => (p.type === "group" ? " " : p.value))
.join("");
Результат:
1 234 567
Такой подход сохраняет локальные правила группировки, но меняет визуальное представление.
Группировка тесно связана с форматированием дробной части:
new Intl.NumberFormat("en-US", {
minimumFractionDigits: 2,
maximumFractionDigits: 2
}).format(1234567);
Результат:
1,234,567.00
При увеличении дробной части группировка целой части остаётся неизменной, но добавляется дополнительный разделитель:
new Intl.NumberFormat("en-US", {
minimumFractionDigits: 3
}).format(1234567.1);
// 1,234,567.100
Система счисления влияет на отображение цифр, но не на группировку.
new Intl.NumberFormat("en-US", {
numberingSystem: "arab"
}).format(1234567);
Результат:
١,٢٣٤,٥٦٧
Группировка сохраняется, но символы заменяются на соответствующие выбранной системе.
Для очень больших значений форматирование остаётся стабильным:
new Intl.NumberFormat("en-US").format(1e20);
// 100,000,000,000,000,000,000
Однако в некоторых локалях возможны ограничения визуального форматирования при использовании compact-режимов:
new Intl.NumberFormat("en-US", {
notation: "compact"
}).format(1234567890);
// 1.2B
В компактной записи классическая группировка заменяется на сокращённую форму.
Группировка сохраняется или модифицируется в зависимости от режима форматирования:
standard — классическая группировкаscientific — экспоненциальная форма, группировка
отсутствуетengineering — группировка заменяется экспонентойcompact — группировка заменяется сокращениямиПример научной нотации:
new Intl.NumberFormat("en-US", {
notation: "scientific"
}).format(1234567);
// 1.234567E6
Создание Intl.NumberFormat — относительно дорогая
операция. При массовом форматировании чисел используется повторное
применение одного экземпляра:
const formatter = new Intl.NumberFormat("en-US");
const values = [1000, 20000, 300000];
values.map(v => formatter.format(v));
Это особенно важно при работе с большими массивами данных, где группировка применяется многократно.
Хотя спецификация ECMAScript стандартизирует API, реализация может отличаться:
useGrouping режимовНесмотря на это, базовая логика группировки остаётся стабильной: она определяется локалью и управляется через Intl API без необходимости ручной реализации разделителей.