> Почему parseInt в JavaScript может возвращать NaN и как влияет второй аргумент (JavaScript)

Уровень: senior · Роль: frontend · Категория: Технические вопросы

Компании: Иннотех

Стек: JavaScript

> Пример ответа

Короткий ответ

parseInt возвращает NaN, когда первый символ строки (после отбрасывания пробелов) не может быть преобразован в цифру в указанной системе счисления, либо когда строка пустая или состоит только из пробелов. Второй аргумент radix задаёт основание системы счисления (от 2 до 36). Если он не указан или равен 0, используется эвристика: строка, начинающаяся с 0x или 0X, трактуется как шестнадцатеричная, иначе - как десятичная. Неверный radix (например, 1 или 37) также приводит к NaN.

Подробное объяснение

parseInt - это функция глобального объекта, которая парсит строку слева направо, пока встречаются допустимые для выбранного основания символы. Как только встречается недопустимый символ, парсинг прекращается, и возвращается уже накопленное число. Если ни одного допустимого символа не найдено - возвращается NaN.

Основные причины NaN:

  • Пустая строка или строка из пробелов.
  • Первый значимый символ не является цифрой или знаком +/- для данного radix.
  • Некорректный radix (вне диапазона 2-36, кроме 0).

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

  • если строка начинается с 0x или 0X - основание 16;
  • иначе - основание 10.

Однако полагаться на эту эвристику не стоит - всегда лучше передавать radix явно. Например, parseInt("08") в некоторых старых реализациях давал 0, а не 8.

Также важно понимать, что parseInt не является строгим парсером: он не выбрасывает исключение, а молча возвращает NaN или частичный результат. Это отличает его от Number() или унарного +, которые возвращают NaN для всей строки целиком.

На практике

В реальном коде parseInt часто используют для извлечения чисел из строк, например, из CSS-значений ("12px"12). Но нужно помнить о двух подводных камнях:

  1. Отсутствие radix - всегда передавайте второй аргумент, чтобы избежать неоднозначности и проблем с восьмеричными числами в старых окружениях.
  2. Частичный парсинг - parseInt("12abc") вернёт 12, что может быть неожиданным. Если нужно строгое преобразование всей строки, используйте Number() или регулярное выражение.

Для проверки результата используйте Number.isNaN() вместо глобального isNaN(), так как последний приводит аргумент к числу и может дать ложное срабатывание (например, isNaN("abc")true, но и isNaN(undefined)true).

Пример кода

JAVASCRIPT
// Базовые случаи
parseInt("42"); // 42
parseInt("42px"); // 42
parseInt(" 42 "); // 42
parseInt(""); // NaN
parseInt("abc"); // NaN
// Влияние radix
parseInt("10", 2); // 2 (двоичная)
parseInt("ff", 16); // 255
parseInt("0x10"); // 16 (эвристика)
parseInt("10", 0); // 10 (0 → десятичная)
parseInt("10", 1); // NaN (radix вне диапазона)
parseInt("10", 37); // NaN
// Частичный парсинг
parseInt("12abc"); // 12
parseInt("abc12"); // NaN
// Проверка результата
const result = parseInt(input, 10);
if (Number.isNaN(result)) {
// обработка ошибки
}

Как отвечать на собеседовании

Начните с определения: parseInt - это функция парсинга строки в целое число с учётом системы счисления. Затем объясните механизм: парсинг идёт до первого недопустимого символа, и если первый символ невалиден - NaN. Обязательно упомяните второй аргумент radix: его диапазон, поведение при 0 или undefined, и почему явное указание - хорошая практика. Приведите пример с "08" для иллюстрации исторических проблем. Завершите рекомендацией использовать Number.isNaN для проверки результата.

Что проверяет интервьюер

Интервьюер оценивает:

  • понимание алгоритма парсинга (постепенное чтение строки);
  • знание особенностей radix и эвристики;
  • осознание разницы между parseInt и Number;
  • умение предвидеть edge cases (пустая строка, пробелы, невалидные символы);
  • практическую привычку всегда передавать второй аргумент.

Типичные ошибки

  • Забывают, что parseInt не проверяет строку целиком - "12abc" вернёт 12.
  • Путают parseInt с Number() или унарным +.
  • Используют глобальный isNaN() вместо Number.isNaN().
  • Не указывают radix, полагаясь на эвристику, что может привести к багам в старых браузерах.
  • Считают, что parseInt("0x10") вернёт 0 - на самом деле вернёт 16, если radix не указан.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью