Комбинирование с NumberFormat

Intl.NumberFormat выступает центральным инструментом форматирования числовых значений в зависимости от локали, культурных правил и контекста отображения. Его основная задача — преобразование числовых данных в человекочитаемое представление с учётом языка, региона, системы счисления, валютных обозначений и правил группировки разрядов.

Ключевая особенность заключается в том, что форматирование не является строковой операцией в классическом смысле. Возвращаемый результат зависит от набора параметров локали и опций:

  • выбор разделителей тысяч и десятичных дробей
  • правила округления
  • отображение валют
  • компактные формы записи
  • единицы измерения

При этом Intl.NumberFormat становится не конечной точкой, а компонентом, который эффективно комбинируется с другими API международализации.


Композиция с Intl.PluralRules для грамматически корректных числовых конструкций

Одной из ключевых задач локализации является корректное согласование числительных с существительными. 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.DateTimeFormat и Intl.NumberFormat работают как независимые форматеры, но объединяются на уровне композиции строк.

Пример структуры:

  • дата форматируется через Intl.DateTimeFormat
  • числовые значения — через Intl.NumberFormat
  • итоговая строка собирается вручную или через шаблонизатор
const 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 как основа глубокого комбинирования

Метод formatToParts возвращает структурированное представление числа, разбитое на семантические компоненты:

  • integer
  • decimal
  • fraction
  • group
  • currency
  • literal

Это позволяет строить сложные 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: '€' }
]

Практическое комбинирование

Такой формат позволяет:

  • оборачивать числа в HTML-элементы
  • стилизовать дробную часть отдельно
  • добавлять интерактивность к валютным символам
  • локализовать отображение без потери структуры
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

В сложных интерфейсах форматирование чисел редко является изолированным действием. Оно включается в шаблоны сообщений, где числа являются переменными.

Комбинация строится следующим образом:

  • Intl.NumberFormat формирует локализованное число
  • шаблонная система подставляет результат в строку
  • дополнительные правила обрабатывают контекст
const nf = new Intl.NumberFormat('ru-RU');

function renderMessage(userCount, activeCount) {
  return `Пользователей: ${nf.format(userCount)}, активных: ${nf.format(activeCount)}`;
}

Расширение через функции форматирования

При масштабировании используется слой функций:

  • единый форматтер на тип данных
  • централизованное управление стилями отображения
  • переиспользование экземпляров Intl.NumberFormat

Локализация интерфейсных компонентов через композицию форматтеров

При проектировании UI-компонентов числовые значения часто используются в разных контекстах:

  • таблицы данных
  • графики
  • карточки статистики
  • финансовые панели

Комбинирование происходит через единый слой форматирования:

  • числовой слой: Intl.NumberFormat
  • грамматический слой: Intl.PluralRules
  • временной слой: Intl.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

Создание экземпляра Intl.NumberFormat является относительно дорогой операцией, особенно при частом рендеринге интерфейсов.

Ключевые принципы оптимизации:

  • кэширование экземпляров по локали и опциям
  • переиспользование форматтеров
  • создание фабрики форматеров

Кэширование через Map

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 поддерживает разные режимы:

  • currency
  • unit
  • percent
  • compact

Комбинирование происходит через единый интерфейс форматирования, где различие определяется только конфигурацией.

const compact = new Intl.NumberFormat('en-US', {
  notation: 'compact'
});

const percent = new Intl.NumberFormat('en-US', {
  style: 'percent'
});

Смешивание компактной записи с UI-логикой

Компактная форма часто используется в аналитических панелях:

  • 1,200 → 1.2K
  • 1,000,000 → 1M

Это форматирование может комбинироваться с formatToParts для выделения суффиксов и стилизации.


Тонкости локализационного комбинирования

При сложной композиции форматеров возникают особенности:

  • различия в порядке символов (валюта до/после числа)
  • разные типы пробелов (non-breaking space)
  • особенности округления
  • локальные системы счисления (арабские, индийские цифры)

Intl.NumberFormat инкапсулирует эти различия, но при комбинировании через строки важно сохранять результат форматтера без повторной обработки.


Архитектурный слой поверх Intl.NumberFormat

В масштабируемых системах Intl.NumberFormat обычно становится частью более широкого слоя:

  • локализационный сервис
  • фабрика форматтеров
  • слой представления данных
  • слой шаблонов

Композиция строится таким образом, что форматирование чисел становится атомарной операцией внутри более сложной системы интернационализации, где каждое API отвечает за узкий аспект локализации и не пересекается с другими по ответственности.