НейроАгент

Форматирование чисел с запятыми в JavaScript: Полное руководство

Узнайте лучшие методы форматирования чисел с запятыми в качестве разделителей тысяч в JavaScript. Изучите встроенные методы Intl, шаблоны regex и оптимизированные решения для производительности для целых чисел и чисел с плавающей точкой.

Вопрос

Как форматировать числа с запятыми в качестве разделителей тысяч в JavaScript?

Я пытаюсь форматировать целые числа в JavaScript с запятыми в качестве разделителей тысяч. Например, я хочу преобразовать число 1234567 в “1,234,567”. Вот моя текущая реализация:

javascript
function numberWithCommas(x) {
    x = x.toString();
    var pattern = /(-?\d+)(\d{3})/;
    while (pattern.test(x))
        x = x.replace(pattern, "$1,$2");
    return x;
}

console.log(numberWithCommas(1000))

Существует ли более простой или элегантный способ добиться этого? Было бы полезно, если бы решение также работало с числами с плавающей запятой, но это не является обязательным требованием. Решение не должно быть специфичным для локали при выборе между точками и запятыми.

НейроАгент

JavaScript предлагает несколько встроенных методов для форматирования чисел с запятыми в качестве разделителей тысяч. Наиболее современный и элегантный подход — использование Intl.NumberFormat или toLocaleString(), которые обеспечивают нативную поддержку в браузерах без ручной манипуляции со строками. Для целых чисел, таких как 1234567, можно просто использовать 1234567.toLocaleString(), чтобы получить “1,234,567”.

Содержание

Встроенные методы

Использование toLocaleString()

Самый простой и элегантный способ — использование встроенного метода toLocaleString():

javascript
const number = 1234567;
const formatted = number.toLocaleString();
console.log(formatted); // "1,234,567"

Этот метод автоматически обрабатывает разделители тысяч и работает как с целыми числами, так и с числами с плавающей точкой:

javascript
console.log(1234567.89.toLocaleString()); // "1,234,567.89"
console.log(1000.toLocaleString());       // "1,000"

Использование Intl.NumberFormat

Для большего контроля и лучшей производительности в циклах используйте Intl.NumberFormat:

javascript
const formatter = new Intl.NumberFormat();
const formatted = formatter.format(1234567);
console.log(formatted); // "1,234,567"

Вы можете создать переиспользуемый форматтер:

javascript
// Создаем переиспользуемый форматтер
const currencyFormatter = new Intl.NumberFormat('en-US', {
    style: 'currency',
    currency: 'USD'
});

// Используем его несколько раз
console.log(currencyFormatter.format(1234567)); // "$1,234,567.00"

Подход с использованием регулярных выражений

Ваша текущая реализация с использованием регулярных выражений функциональна, но может быть упрощена:

javascript
function numberWithCommas(x) {
    return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}

console.log(numberWithCommas(1234567)); // "1,234,567"

Этот шаблон регулярного выражения \B(?=(\d{3})+(?!\d)) использует позитивную опережающую проверку для поиска позиций, которые:

  • \B — Не находятся на границе слова (гарантирует, что мы не добавляем запятые в начале)
  • (?=(\d{3})+) — За которыми следуют группы ровно из 3 цифр
  • (?!\d) — Не за которыми следуют какие-либо цифры (гарантирует, что мы не добавляем запятые в конце)

Ручная манипуляция со строками

Для сред без поддержки Intl или когда требуется максимальный контроль:

javascript
function formatNumberWithCommas(num) {
    const parts = num.toString().split('.');
    parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',');
    return parts.join('.');
}

console.log(formatNumberWithCommas(1234567));      // "1,234,567"
console.log(formatNumberWithCommas(1234567.89));   // "1,234,567.89"

Сравнение методов

Метод Производительность Поддержка в браузерах Гибкость Сложность кода
toLocaleString() Хорошая Все современные браузеры Высокая Очень простая
Intl.NumberFormat Отличная (кэшируется) Все современные браузеры Очень высокая Простая
Регулярные выражения Умеренная Все браузеры Средняя Умеренная
Ручной парсинг Хорошая Все браузеры Низкая Простая

Работа с числами с плавающей точкой

Все встроенные методы автоматически обрабатывают десятичные точки:

javascript
const number = 1234567.8912;

// Используем toLocaleString
console.log(number.toLocaleString()); // "1,234,567.891"

// Используем Intl.NumberFormat
const formatter = new Intl.NumberFormat('en-US', {
    minimumFractionDigits: 2,
    maximumFractionDigits: 4
});
console.log(formatter.format(number)); // "1,234,567.8912"

Для ваших конкретных потребностей можно создать простую обертку:

javascript
function formatNumber(num) {
    return num.toLocaleString();
}

// Работает и с целыми, и с дробными числами
console.log(formatNumber(1234567));    // "1,234,567"
console.log(formatNumber(1234567.89)); // "1,234,567.89"

Поддержка в браузерах и альтернативы

Современные браузеры (Chrome, Firefox, Safari, Edge)

Все современные браузеры полностью поддерживают Intl.NumberFormat и toLocaleString() с отличной производительностью.

Устаревшие браузеры (Internet Explorer)

Для старых браузеров можно использовать полифилл или вернуться к подходу с регулярными выражениями:

javascript
if (!window.Intl) {
    // Резервный вариант для старых браузеров
    function formatNumber(num) {
        return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
    }
} else {
    // Современный подход
    function formatNumber(num) {
        return num.toLocaleString();
    }
}

Решения на основе библиотек

Для расширенных потребностей в форматировании рассмотрите библиотеки:

Вопросы производительности

При форматировании большого количества значений Intl.NumberFormat наиболее эффективен при кэшировании:

javascript
// Кэшируем форматтер для лучшей производительности в циклах
const numberFormatter = new Intl.NumberFormat();

function formatManyNumbers(numbers) {
    return numbers.map(num => numberFormatter.format(num));
}

// Значительно быстрее, чем вызов toLocaleString() каждый раз
const largeArray = Array.from({length: 1000}, (_, i) => i * 1000 + 123);
const formatted = formatManyNumbers(largeArray);

Заключение

Для вашего случая использования самым простым и элегантным решением является использование toLocaleString():

javascript
function numberWithCommas(x) {
    return x.toLocaleString();
}

console.log(numberWithCommas(1234567)); // "1,234,567"

Ключевые выводы:

  1. Предпочтение встроенным методам: toLocaleString() и Intl.NumberFormat являются наиболее надежными и поддерживаемыми решениями
  2. Производительность имеет значение: Для массовых операций кэшируйте экземпляры Intl.NumberFormat
  3. Совместимость: Современные браузеры отлично обрабатывают все эти методы
  4. Простота сложнее: Ваш подход с регулярными выражениями работает, но не так чист, как встроенные решения
  5. Гибкость: Встроенные методы автоматически обрабатывают как целые, так и дробные числа

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

Источники

  1. MDN Web Docs - Intl.NumberFormat
  2. MDN Web Docs - Number.prototype.toLocaleString
  3. Спецификация ECMAScript Internationalization API
  4. Can I Use - Intl API