Форматирование денежных значений в JavaScript реализуется через
Intl.NumberFormat с указанием параметра
style: "currency". Этот режим автоматически применяет
локализацию: разделители, порядок символов, отображение валютного знака
и правила округления зависят от выбранной локали и валюты.
Ключевая структура:
new Intl.NumberFormat(locale, {
style: "currency",
currency: "USD"
})
Параметр currency является обязательным при
использовании стиля "currency". Без него форматирование не
будет выполнено корректно.
Локаль определяет:
Примеры одной и той же суммы:
const value = 1234567.89;
new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD"
}).format(value);
// $1,234,567.89
new Intl.NumberFormat("de-DE", {
style: "currency",
currency: "EUR"
}).format(value);
// 1.234.567,89 €
new Intl.NumberFormat("ja-JP", {
style: "currency",
currency: "JPY"
}).format(value);
// ¥1,234,568
Особенность японской иены — отсутствие десятичных знаков в большинстве случаев, что автоматически учитывается стандартом.
Значение currency задаётся в формате ISO 4217:
new Intl.NumberFormat("ru-RU", {
style: "currency",
currency: "RUB"
}).format(9999);
// 9 999,00 ₽
Использование невалидного кода приводит к
RangeError.
Параметр currencyDisplay определяет способ отображения
валютного символа:
new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
currencyDisplay: "symbol"
}).format(100);
// $100.00
Отображение ISO-кода валюты:
new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
currencyDisplay: "code"
}).format(100);
// USD 100.00
Полное текстовое название валюты:
new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
currencyDisplay: "name"
}).format(100);
// 100.00 US dollars
Сокращённый символ, особенно полезный в ограниченном пространстве интерфейса:
new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
currencyDisplay: "narrowSymbol"
}).format(100);
// $100.00
Параметр currencySign влияет на отображение
отрицательных значений.
Обычное отображение минуса:
new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
currencySign: "standard"
}).format(-50);
// -$50.00
Бухгалтерский формат: отрицательные значения оборачиваются в скобки:
new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
currencySign: "accounting"
}).format(-50);
// ($50.00)
Этот формат широко используется в финансовой отчётности.
Формат валюты по умолчанию применяет округление, соответствующее
валюте (например, 2 знака для USD, 0 для JPY). Управление осуществляется
через minimumFractionDigits и
maximumFractionDigits.
new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
maximumFractionDigits: 0
}).format(123.99);
// $124
new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
minimumFractionDigits: 3
}).format(10);
// $10.000
Intl учитывает особенности валют:
new Intl.NumberFormat("en-US", {
style: "currency",
currency: "KWD"
}).format(12.3456);
// KWD 12.346
Эти правила встроены в CLDR (Unicode Common Locale Data Repository).
Отрицательные суммы отображаются в зависимости от локали и настроек
currencySign.
new Intl.NumberFormat("ru-RU", {
style: "currency",
currency: "RUB"
}).format(-1500);
// -1 500,00 ₽
new Intl.NumberFormat("de-DE", {
style: "currency",
currency: "EUR",
currencySign: "accounting"
}).format(-1500);
// (1.500,00 €)
Разделение числа на разряды регулируется
useGrouping.
new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
useGrouping: false
}).format(1000000);
// $1000000.00
new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
useGrouping: true
}).format(1000000);
// $1,000,000.00
Некоторые валюты не используют дробную часть. Intl автоматически корректирует формат:
new Intl.NumberFormat("ja-JP", {
style: "currency",
currency: "JPY"
}).format(1500.75);
// ¥1,501
Дробная часть отбрасывается с корректным округлением по математическим правилам.
Создание экземпляра Intl.NumberFormat относительно
дорогостоящая операция. Эффективная практика — переиспользование:
const usdFormatter = new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD"
});
usdFormatter.format(10);
usdFormatter.format(999);
usdFormatter.format(12345);
Такой подход снижает накладные расходы при массовом форматировании данных.
При обработке больших наборов данных форматтер применяется как функция:
const formatter = new Intl.NumberFormat("de-DE", {
style: "currency",
currency: "EUR"
});
const prices = [10, 20.5, 30, 99.99];
const formatted = prices.map(formatter.format);
// ["10,00 €", "20,50 €", "30,00 €", "99,99 €"]
Важно сохранять контекст метода при передаче format,
иначе возможна потеря привязки:
prices.map((n) => formatter.format(n));
В разных регионах различается не только символ валюты, но и:
new Intl.NumberFormat("fr-FR", {
style: "currency",
currency: "EUR"
}).format(42);
// 42,00 €
new Intl.NumberFormat("en-GB", {
style: "currency",
currency: "GBP"
}).format(42);
// £42.00
Intl.NumberFormat поддерживает сочетание валютного
формата с дополнительными настройками:
notation (standard, compact, scientific)signDisplayminimumIntegerDigitsОднако при использовании style: "currency" часть
параметров игнорируется или ограничивается спецификацией валютного
формата.
new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
signDisplay: "always"
}).format(50);
// +$50.00
При отсутствии поддержки локали происходит fallback на ближайшую доступную:
new Intl.NumberFormat("xx-XX", {
style: "currency",
currency: "USD"
}).format(100);
Результат будет соответствовать дефолтной локали окружения, сохраняя корректный валютный формат.
Форматирование валюты внутри Intl проходит несколько этапов:
Эта последовательность обеспечивает единообразное отображение финансовых значений во всех поддерживаемых средах JavaScript.