popov . dev

Главная

Библиотека

Статьи

Подводные камни ...

Подводные камни при использовании parseInt в JavaScript

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

В этой статье мы рассмотрим загадочное поведение функции parseInt() в JavaScript, чтобы дать четкое представление о том, как она работает, ее ограничениях и рекомендациях по ее использованию.

Парсинг int из разных систем счислений

Функция parseInt() имеет необязательный второй аргумент radix, который позволяет анализировать целые числа из разных числовых баз. Параметром radix может быть любое целое число в диапазоне от 2 до 36. Если он не указан, parseInt принимает значение radix равным 10. Параметр radix указывает parseInt, какую систему счисления использовать для интерпретации строки. Например, если значение radix равно 16, parseInt интерпретирует строку как шестнадцатеричное число.

Вот как разобрать числовую строку в двоичной системе:

const number = parseInt('100', 2);
number; // 4

В этом примере parseInt('100', 2) анализирует двоичную строку '100' как целое число с основанием 2, возвращая десятичное значение 4.

Магия parseInt() и чисел с плавающей запятой

При использовании функции parseInt() для извлечения целой части чисел с плавающей запятой результаты иногда могут быть неожиданными:

console.log(parseInt(0.5));      // Output: 0
console.log(parseInt(0.05));     // вывод: 0
console.log(parseInt(0.005));    // вывод: 0
console.log(parseInt(0.0005));   // вывод: 0
console.log(parseInt(0.00005));  // вывод: 0
console.log(parseInt(0.000005)); // вывод: 0
console.log(parseInt(0.0000005)); // вывод: 5

Загадочное поведение возникает из-за того, что функция parseInt() преобразует свой первый аргумент в строку, а числа, меньшие 10-6, при преобразовании в строку записываются в экспоненциальной системе счисления. Когда функция parseInt() обрабатывает экспоненциальную запись, она учитывает только значительную часть записи:

String(0.0000005); // => '5e-7'
parseInt('5e-7');  // => 5

Чтобы извлечь целую часть числа с плавающей запятой, вы можете вместо этого использовать функцию Math.floor. Например:

console.log(Math.floor(0.0000005)); // Вывод: 0

Ограничения чисел в JavaScript

JavaScript представляет все числа, используя стандарт IEEE 754 для арифметики с плавающей запятой, что означает, что он может хранить числа только с определенным уровнем точности. Большие числа или числа, которые могут потерять точность, могут привести к нелогичному поведению при использовании parseInt(). Например:

parseInt(999999999999999999999); // => 1

В этом случае большое число округляется до ближайшего представимого числа 1e+21. Когда функция parseInt() обрабатывает число, она учитывает только значительную часть экспоненциальной записи, что приводит к результату, равному 1.

String(999999999999999999999); // => '1e+21'
parseInt('1e+21');  // => 1

Чтобы обойти это ограничение, вы можете использовать тип данных BigInt, представленный в ECMAScript 2020. Тип данных BigInt позволяет представлять целые числа произвольной длины, включая очень большие целые числа.

const num = BigInt("999999999999999999999");
console.log(num); // вывод: 999999999999999999999n

Нездоровое поведение parseInt() с нечисловыми строками

Другим интересным аспектом функции parseInt() является ее поведение с нечисловыми строками. При получении нечисловой строки функция parseInt() пытается проанализировать строку до тех пор, пока не достигнет нечислового символа:

parseInt('42px');      // => 42
parseInt('0xF');       // => 15
parseInt('123abc456'); // => 123

Однако, если строка начинается с нечислового символа, функция parseInt() возвращает значение NaN:

parseInt(true); // => NaN
parseInt(false); // => NaN
parseInt('px42'); // => NaN

Аналогично, при использовании parseInt() с массивом массив сначала преобразуется в строку, а затем parseInt() пытается проанализировать строку:

parseInt([42]);       // => 42
parseInt(['42px']);   // => 42
parseInt([1, 2, 3]);  // => 1

Практические рекомендации и альтернативы parseInt()

Учитывая особенности и возможные подводные камни функции parseInt(), важно следовать рекомендациям при ее использовании. Некоторые рекомендации включают:

  • Всегда указывайте аргумент radix, чтобы избежать путаницы и возможных ошибок, связанных с разными числовыми базами. Number - лучший выбор при преобразовании в десятичные числа.
  • Избегайте использования функции parseInt() для извлечения целой части чисел с плавающей запятой. Вместо этого используйте Math.floor(), Math.ceil() или Math.round(), в зависимости от ваших требований.
  • Будьте осторожны при использовании parseInt() с большими числами или числами, которые могут привести к потере точности. Рассмотрите возможность использования специализированных библиотек, таких как BigInt или BigNumber, для точной обработки больших чисел.
  • Помните о нелогичном поведении при анализе нечисловых строк или при неявном преобразовании типов. Убедитесь, что входные данные, предоставляемые parseInt(), соответствуют ожидаемому типу данных и формату.

Заключение

Понимание загадочных и противоречащих здравому смыслу правил parseInt() имеет решающее значение для разработчиков JavaScript. Хотя это мощный инструмент для анализа целых чисел из числовых строк, у него также есть несколько нюансов, которые могут привести к неожиданным результатам.

Комментарии

Для того чтобы оставить свое мнение, необходимо зарегистрироваться на сайте