Как форматировать число с разделением тысяч запятыми в JavaScript?
Лучший способ: использовать toLocaleString()
Самый простой и надёжный способ форматирования чисел с разделением тысяч — это встроенный метод Number.prototype.toLocaleString(). Он не только добавляет запятые, но и корректно обрабатывает отрицательные числа, десятичные дроби, а также учитывает локальные настройки (например, в некоторых странах используют точки или пробелы).
const number = 1234567.89;
console.log(number.toLocaleString()); // "1,234,567.89" (для локали en-US)
// Для отрицательных чисел:
const negative = -1234567.89;
console.log(negative.toLocaleString()); // "-1,234,567.89"
// Если нужно гарантировать американский формат (запятые и точки):
console.log(number.toLocaleString('en-US')); // "1,234,567.89"
// Для целых чисел:
const integer = 1234567;
console.log(integer.toLocaleString('en-US')); // "1,234,567"
Как это работает?
Метод toLocaleString() принимает два необязательных аргумента:
- locale (строка) — код языка и региона, например
'en-US'(английский, США),'de-DE'(немецкий, Германия — там используют точки как разделители тысяч и запятые для дробной части). - options (объект) — дополнительные настройки форматирования, такие как
minimumFractionDigits,maximumFractionDigits,style(для валюты или процентов) и другие.
Пример с настройками:
const price = 1234567.8912;
console.log(price.toLocaleString('en-US', {
minimumFractionDigits: 2,
maximumFractionDigits: 2
}));
// "1,234,567.89" — округлено до двух знаков после запятой
Если нужно только разделение тысяч (без локализации)
Если вы хотите гарантированно использовать запятые в качестве разделителя тысяч и точку для десятичной части, независимо от локали пользователя, можно создать простую функцию:
function formatWithCommas(x) {
// Разделяем целую и дробную части
const parts = x.toString().split('.');
// Форматируем целую часть с помощью регулярного выражения
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',');
return parts.join('.');
}
console.log(formatWithCommas(1234567.89)); // "1,234,567.89"
console.log(formatWithCommas(-1234567)); // "-1,234,567"
console.log(formatWithCommas(123456)); // "123,456"
Объяснение регулярного выражения
\B— соответствует позиции, где нет границы слова (т.е. внутри числа).(?=(\d{3})+(?!\d))— положительный просмотр вперёд: проверяет, что за текущей позицией следует одна или более групп из трёх цифр, после которых нет цифры.- Этот метод не затрагивает дробную часть и правильно обрабатывает отрицательные числа, так как минус не является цифрой.
Почему ваш код не работал?
Ваш код пытался вставлять запятые с конца, но логика с i % 3 === 0 неверна: вы начинали отсчёт с первой цифры слева, а нужно с конца. Кроме того, он не обрабатывал десятичные числа и отрицательные значения. Используйте готовые решения — они проверены временем.
Рекомендация: для большинства проектов используйте toLocaleString() — он встроен в JavaScript, поддерживается во всех современных браузерах и Node.js, и автоматически адаптируется под регион пользователя. Если нужен строгий формат (всегда запятые), используйте регулярное выражение.
Альтернативный подход: Intl.NumberFormat
Если вам нужно больше контроля над форматированием, используйте объект Intl.NumberFormat. Он является более производительным, чем toLocaleString(), если вы форматируете много чисел, так как его можно создать один раз и переиспользовать.
const formatter = new Intl.NumberFormat('en-US', {
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
console.log(formatter.format(1234567.891)); // "1,234,567.89"
console.log(formatter.format(-9876543.21)); // "-9,876,543.21"
console.log(formatter.format(1000)); // "1,000.00"
Для форматирования валюты
С помощью Intl.NumberFormat легко добавить символ валюты:
const currencyFormatter = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
minimumFractionDigits: 2
});
console.log(currencyFormatter.format(1234567.89)); // "$1,234,567.89"
Когда это полезно?
- Если вы форматируете числа в цикле (например, выводите список цен), создайте объект
Intl.NumberFormatодин раз вне цикла — это ускорит выполнение. - Если нужно поддерживать разные локали динамически, можно менять
localeпри создании экземпляра. - Этот метод также корректно работает с отрицательными числами и дробями.
Оба подхода (toLocaleString и Intl.NumberFormat) являются стандартными и рекомендуемыми. Выбирайте тот, который удобнее в вашем контексте.