Как в JavaScript добавить запятые при форматировании чисел? Подробное руководство
Вы когда-нибудь задумывались, почему 1000000 читается с трудом, а 1,000,000 — мгновенно? Человеческий глаз просто не создан для длинных цифровых рядов. Разделители тысяч (commas, пробелы или точки) — это не просто вопрос эстетики, а вопрос юзабилити и восприятия информации.
Если вы пишете на JavaScript и работаете с ценами, статистикой, ID или любыми числовыми данными, рано или поздно встанет вопрос: «Как отформатировать число, добавив запятые или пробелы между тысячными разрядами?». На Stack Overflow этот вопрос набрал тысячи просмотров — значит, он волнует многих.
В этой статье мы не просто дадим готовый код. Мы разберем три основных способа: от современного встроенного API до классических регулярных выражений. Вы узнаете, как заставить JavaScript «говорить» на языке читабельных чисел. Поехали!
Почему простое число — это проблема?
Представьте, что выводите на сайт: Цена: 1234567.89 руб.. Глаз спотыкается. Сколько это? Миллион? Двенадцать миллионов? А если добавить запятые: 1,234,567.89 — сразу ясно: чуть больше миллиона.
В JavaScript число — это просто Number. У него нет «встроенного» формата отображения. Всё, что мы видим — это результат преобразования в строку. И тут вступаем в игру мы, разработчики.
Способ 1: toLocaleString() — король простоты
Самый элегантный и современный способ — использовать метод toLocaleString(). Он есть у любого числа в JavaScript и позволяет учесть локаль пользователя.
const number = 1234567.89;
const formatted = number.toLocaleString('ru-RU');
console.log(formatted); // "1 234 567,89"
Обратите внимание: для русской локали (ru-RU) разделитель тысяч — это неразрывный пробел, а десятичный разделитель — запятая. Для американской (en-US) — запятая и точка:
console.log(number.toLocaleString('en-US')); // "1,234,567.89"
Плюсы:
- Минимум кода.
- Учитывает локальные стандарты (пробелы, точки, запятые).
- Работает во всех современных браузерах и Node.js.
Минусы:
- Меньше контроля над форматом (нельзя просто заменить пробел на запятую без дополнительных манипуляций).
- Старые браузеры (IE11) могут не поддерживать второй аргумент (locales).
Способ 2: Intl.NumberFormat — гибкость и мощь
Если вам нужен полный контроль, используйте объект Intl.NumberFormat. Это тот же механизм, что и у toLocaleString(), но с расширенными настройками.
const formatter = new Intl.NumberFormat('ru-RU', {
style: 'decimal',
useGrouping: true, // Включает разделители тысяч
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
console.log(formatter.format(1234567.8)); // "1 234 567,80"
Хотите валюту? Легко:
const currencyFormatter = new Intl.NumberFormat('ru-RU', {
style: 'currency',
currency: 'USD',
minimumFractionDigits: 0
});
console.log(currencyFormatter.format(1000000)); // "1 000 000 $"
Можно менять разделитель тысяч вручную? Прямой опции нет, но можно сделать replace:
let result = formatter.format(1234567.89);
result = result.replace(/\s/g, ','); // Заменяем пробелы на запятые
console.log(result); // "1,234,567,80"
Плюсы:
- Максимальная гибкость (валюта, проценты, единицы измерения).
- Производительность (можно создать один раз и переиспользовать).
Минусы:
- Чуть больше кода, чем toLocaleString().
- Всё ещё зависит от локали.
Способ 3: Классика — регулярные выражения и циклы
Иногда нужно решение, которое не зависит от локали и работает везде, включая древние браузеры. Тут на помощь приходят регулярные выражения.
Самый популярный вариант — добавить запятые (или пробелы) каждые 3 цифры слева от десятичной точки.
function formatWithCommas(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
console.log(formatWithCommas(1234567.89)); // "1,234,567.89"
console.log(formatWithCommas(1000)); // "1,000"
console.log(formatWithCommas(-1234567)); // "-1,234,567"
Как это работает?
\B— граница не-слова (чтобы не вставить запятую в начало числа).(?=(\d{3})+(?!\d))— позитивный просмотр вперед, который ищет группы из 3 цифр, за которыми не следует цифра.
Если вам нужны пробелы вместо запятых:
function formatWithSpaces(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, " ");
}
console.log(formatWithSpaces(1234567.89)); // "1 234 567.89"
Плюсы:
- Абсолютный контроль.
- Не зависит от локали.
- Работает в любом JS-окружении.
Минусы:
- Регулярное выражение выглядит как магия (но мы её только что развеяли).
- Не учитывает дробную часть (но это и не нужно — она справа от точки).
Сравнение методов: что выбрать?
| Метод | Когда использовать | Производительность |
|---|---|---|
| toLocaleString | Быстрое решение, если не нужен кастомный формат | Хорошая |
| Intl.NumberFormat | Сложные форматы (валюта, проценты) или частая переработка | Отличная (особенно при переиспользовании) |
| RegExp | Старые браузеры, полный контроль, нет зависимости от локали | Хорошая (зависит от длины числа) |
Лайфхаки и подводные камни
1. Отрицательные числа
Все методы корректно работают с отрицательными числами. Минус остаётся на месте, а разделители добавляются к модулю числа.