Back

Как парсить числа в JavaScript

Как парсить числа в JavaScript

Когда вы считываете значение из поля формы, параметра URL или ответа JSON API, оно почти всегда приходит в виде строки. Прежде чем выполнять с ним какие-либо математические операции, необходимо преобразовать его в число. JavaScript предоставляет несколько способов сделать это, и они ведут себя достаточно по-разному, чтобы выбор неправильного метода приводил к неочевидным ошибкам. Эта статья охватывает основные методы, когда использовать каждый из них, и граничные случаи, которые чаще всего ставят разработчиков в тупик.

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

  • parseInt() и parseFloat() выполняют частичный парсинг, читая слева направо и останавливаясь на первом недопустимом символе — полезно для строк вроде "24px".
  • Number() и унарный + требуют, чтобы вся строка была валидной, иначе возвращают NaN — идеально для строгих преобразований данных из API.
  • Всегда передавайте radix в parseInt() и всегда проверяйте результаты с помощью Number.isNaN(), а не глобального isNaN().
  • Используйте BigInt() для целых чисел, превышающих Number.MAX_SAFE_INTEGER, и нормализуйте строки с локальным форматированием перед парсингом.

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

МетодВвод "42px"Ввод "3.14"Ввод ""Ввод "abc"
parseInt("42px", 10)423NaNNaN
parseFloat("42px")423.14NaNNaN
Number("42px")NaN3.140NaN
+"42px"NaN3.140NaN

parseInt(): частичный парсинг для целых чисел

parseInt(string, radix) читает символы слева направо и останавливается в момент, когда встречает что-то, что не может распарсить. Это делает его полезным для строк вроде "24px" или "10rem", где число идёт первым.

parseInt("24px", 10)   // 24
parseInt("3.99", 10)   // 3  (десятичная точка останавливает парсинг)
parseInt("abc", 10)    // NaN (первый символ недопустим)

Всегда передавайте radix. Без него parseInt обрабатывает строки, начинающиеся с 0x, как шестнадцатеричные, а в остальных случаях парсит в основании 10. Хотя современные движки по умолчанию используют основание 10, пропуск radix является известным источником ошибок и делает ваши намерения неясными.

parseInt("0xFF", 16)   // 255 — явный парсинг hex
parseInt("011", 10)    // 11  — radix предотвращает неоднозначность

Одно неочевидное поведение: parseInt останавливается на десятичной точке в "6.022e23", поэтому parseInt("6.022e23", 10) возвращает 6, а не 602200000000000000000000. Не используйте parseInt для усечения больших чисел с плавающей точкой. Вместо этого используйте Math.trunc().


parseFloat(): частичный парсинг для десятичных чисел

parseFloat() работает так же, как parseInt, но сохраняет десятичную часть. У него нет параметра radix, и он всегда парсит в основании 10.

parseFloat("3.14rem")  // 3.14
parseFloat("1e3")      // 1000 — понимает научную нотацию
parseFloat("px10")     // NaN  — первый символ недопустим

Используйте parseFloat, когда входные данные могут содержать десятичное значение, и вы хотите его сохранить.


Number() и унарный +: строгое преобразование

И Number(), и унарный оператор + требуют, чтобы вся строка была валидным числом. Если какая-либо её часть таковой не является, вы получите NaN. Эта строгость является преимуществом при работе с ответами API или валидированными данными форм, где частичный парсинг был бы скрытой ошибкой.

Number("42")     // 42
Number("3.14")   // 3.14
Number("42px")   // NaN — строже, чем parseInt
Number("")       // 0   — обратите внимание на это
+"42"            // 42  — идентичное поведение, более короткий синтаксис

Граничный случай с пустой строкой важен при обработке форм. Number("") возвращает 0, а не NaN, что может скрыть отсутствующее значение. Всегда проверяйте пустой ввод перед преобразованием.


Числовые разделители не работают во время выполнения

Исходный код JavaScript допускает 1_000_000 как числовой литерал, но этот синтаксис не переносится на парсинг строк.

parseInt("1_000", 10)   // 1 — парсинг останавливается на подчёркивании
Number("1_000")         // NaN

Если ваш API или пользовательский ввод использует подчёркивания как разделители тысяч, сначала удалите их с помощью str.replace(/_/g, "").


BigInt(): парсинг больших целых чисел

Тип Number в JavaScript теряет точность за пределами Number.MAX_SAFE_INTEGER (2⁵³ − 1). Для значений больше этого — ID баз данных, криптографические значения, финансовые целые числа — используйте BigInt().

BigInt("9007199254740993")   // 9007199254740993n — точное значение
Number("9007199254740993")   // 9007199254740992  — ошибка на единицу

Передавайте строку напрямую в BigInt(). Не пропускайте её сначала через parseInt, потому что точность уже теряется на этом этапе. Обратите внимание, что значения BigInt нельзя смешивать с обычными значениями Number в арифметических операциях без явного преобразования.


Парсинг с учётом локали

В JavaScript нет встроенной функции для парсинга чисел в локальном формате, таких как "1.234,56" (распространено в немецкой или испанской локалях). Вам нужно вручную нормализовать строку перед парсингом:

const raw = "1.234,56"
const normalized = raw.replace(/\./g, "").replace(",", ".")
parseFloat(normalized) // 1234.56

Какой метод следует использовать?

  • Пользовательский ввод или CSS-значения с единицами измеренияparseInt(str, 10) или parseFloat()
  • Ответы API или строго валидированные данныеNumber() или унарный +
  • Целые числа за пределами 2⁵³ − 1BigInt()
  • Всегда проверяйте, что результат не является NaN, перед его использованием:
const qty = parseInt(input, 10)
if (Number.isNaN(qty)) {
  // обработка недопустимого ввода
}

Используйте Number.isNaN(), а не глобальный isNaN(). Глобальная версия сначала приводит свой аргумент к типу, что означает, что isNaN("") возвращает false, хотя "" не является числом.


Заключение

Правильный метод парсинга чисел в JavaScript зависит от того, что вы знаете о своих входных данных. Используйте parseInt или parseFloat, когда частичный парсинг приемлем и ожидаем. Используйте Number() или унарный +, когда вся строка должна быть валидным числом. Обращайтесь к BigInt(), когда точность важна для больших целых чисел. Во всех случаях проверяйте на NaN перед использованием результата.

Часто задаваемые вопросы

parseInt читает строку слева направо и останавливается на первом символе, который не может интерпретировать как часть целого числа. Number требует, чтобы вся строка была валидным числовым значением. Например, parseInt от 42px возвращает 42, в то время как Number от 42px возвращает NaN. Используйте parseInt для частичного парсинга и Number для строгого преобразования.

Спецификация ECMAScript определяет, что пустая строка преобразуется в 0 при передаче в Number или унарный оператор плюс. Это может скрыть отсутствующие значения форм. Всегда проверяйте, является ли входная строка пустой, перед преобразованием её в число, чтобы избежать обработки пустых полей как нуля.

Используйте BigInt, когда целое число превышает Number.MAX_SAFE_INTEGER, который равен 2 в степени 53 минус 1. За этим порогом Number теряет точность и может незаметно округлять значения. Передавайте числовую строку напрямую в BigInt, а не преобразовывайте сначала через parseInt или Number, поскольку точность теряется на этом промежуточном этапе.

Глобальный isNaN приводит свой аргумент к числу перед проверкой, что даёт вводящие в заблуждение результаты. Например, isNaN от пустой строки возвращает false, потому что пустая строка приводится к 0. Number.isNaN пропускает приведение типов и возвращает true только если значение буквально является NaN, что делает его надёжным выбором для валидации.

Complete picture for complete understanding

Capture every clue your frontend is leaving so you can instantly get to the root cause of any issue with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.

Check our GitHub repo and join the thousands of developers in our community.

OpenReplay