12k
All articles

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

Сравнение parseInt, parseFloat, Number и BigInt для преобразования строк в числа в JavaScript, включая разбор граничных случаев, приводящих к скрытым ошибкам.

OpenReplay Team
OpenReplay Team
Как парсить числа в 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 в JavaScript?

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

Почему Number от пустой строки возвращает 0 вместо NaN?

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

Когда следует использовать BigInt вместо Number для парсинга?

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

Почему следует использовать Number.isNaN вместо глобальной функции isNaN?

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

Open-source session replay

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.

Star on GitHub12k

We use cookies to improve your experience. By using our site, you accept cookies.