Функция parseInt() в JavaScript: руководство по преобразованию строк в числа

Извлекаем нужные данные для работы

Функция parseInt() в JavaScript: руководство по преобразованию строк в числа

Преобразование строки в число — одна из самых частых задач в разработке. На фронтенде это нужно при работе с формами, стилями, атрибутами, данными из API или localStorage — потому что всё это приходит как строки. На бэке тоже такое нужно: числа в строковом виде из баз, JSON, параметры запросов. И чтобы из «42» или «100px» достать нормальное целое число, используют метод parseInt(). Рассказываем, в чём его сила.

Что такое parseInt() в JavaScript?

Если формально, то parseInt() — это встроенная функция, которая превращает строку в целое число по определённым правилам. Она читает строку слева направо и выхватывает всё, что похоже на число, пока не дойдёт до нечислового символа.

Назначение и базовый синтаксис

Главная задача parseInt() — взять строку и вернуть из неё целое число. Синтаксис такой:

parseInt(string, radix);

Где:

  • string — строка, которую мы хотим разобрать;
  • radix — система счисления (например, 10 для десятичной, 16 для шестнадцатеричной и т. д.).

Посмотрим на примерах:

parseInt(“42”);       // 42

Здесь у нас просто число в строке. Без указанного radix оно парсится как десятичное.

Если в строке сначала идут цифры — parseInt() берёт их, а всё после нечислового “px” игнорирует:

parseInt(“10px”); // 10

Удобно, если нужно вытянуть число из CSS-значения.

Можно работать с числами в разных системах счисления, например в шестнадцатеричной:

parseInt(“0xFF”, 16); // 255

Здесь указана двоичная система (radix = 2), и поэтому “1010” становится десяткой:

parseInt(“1010”, 2); // 10

Полезный блок со скидкой

Если вам интересно разбираться со смартфонами, компьютерами и прочими гаджетами и вы хотите научиться создавать софт под них с нуля или тестировать то, что сделали другие, — держите промокод Практикума на любой платный курс: KOD (можно просто на него нажать). Он даст скидку при покупке и позволит сэкономить на обучении.

Бесплатные курсы в Практикуме тоже есть — по всем специальностям и направлениям, начать можно в любой момент, карту привязывать не нужно, если что.

Отличие от других методов преобразования (Number(), parseFloat())

В JavaScript есть несколько способов превратить строку в число: кроме parseInt(), есть унарный плюс +, а также методы Number() и parseFloat(). Все они вроде делают одно и то же, но ведут себя по-разному.

Number()

Требует, чтобы вся строка была строго числом. Если там будет хоть один лишний символ, то получим NaN:

Number(“123px”); // NaN

Унарный плюс +

Работает почти так же, как Number(), но в виде короткой записи. Это быстрый и максимально ленивый способ привести значение к числу.

+"123";     // 123
+"12.5";    // 12.5
+"12px";    // NaN (так же как Number)

Унарный плюс часто используют, когда надо быстро конвертировать значение, например, из input.value, без вызова Number() или parseFloat().

parseFloat()

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

parseFloat(“123.45px”); // 123.45

Если строка может содержать какие-то единицы измерения или случайные символы, то используют parseInt() и parseFloat(). А Number() и + подойдут для случаев, когда мы точно знаем, что в строке только число.

Синтаксис parseInt()

Функция parseInt() принимает два параметра — string и radix, разберём каждый из них подробно.

string (обязательный)

То, что будет парситься. Обычно это строка, но если мы передадим что-то другое (например, число, null, объект), то parseInt() сначала приведёт это к строке, а потом уже начнёт работать с ней.

parseInt("42px");     // 42
parseInt("   007")    // 7 (пробелы игнорируются)
parseInt("abc123");   // NaN
parseInt(true);       // NaN (потому что "true" не начинается с цифры)

radix (необязательный, но желательный)

В этом параметре мы прописываем систему счисления — от 2 до 36. Если вы работаете в десятичной системе, всегда передавайте 10 вторым аргументом. Потому что если не передать — parseInt() будет сам угадывать систему, что может привести к ошибкам.

parseInt(“10”, 10); // 10
parseInt(“10”, 2); // 2 — это двоичная десятка
parseInt(“1f”, 16); // 31 — шестнадцатеричная система

Если передать radix, который выходит за пределы от 2 до 36, то будет NaN.

parseInt(“123”, 1); // NaN
parseInt(“123”, 37); // NaN

Как работает parseInt()

На первый взгляд кажется, что parseInt() просто берёт строку и делает из неё число. Но под капотом у него своя логика: правила разбора, условия отказа и не всегда очевидные обрезки.

Преобразование строки в целое число

Разберёмся, по какому алгоритму работает parseInt().

Сначала всё превращается в строку. Даже если мы передаём null, булево значение, объект или даже число — parseInt() сначала приводит это значение к строке через String():

parseInt(null);    // NaN, потому что "null" не число
parseInt(123);     // 123
parseInt(true);    // NaN

Затем метод удаляет пробелы в начале и читает знак. В начале строки могут быть пробелы, + или −. Это нормально читается только в начале строки:

parseInt(” -42″); // -42

Если + или − появятся где-то позже, parseInt() просто остановится:

parseInt(“12-34”); // 12 — минус не на месте

Определяет систему счисления (если radix не указан или равен 0). Если мы не передали radix, движок попробует угадать:

  • Если строка начинается с 0x или 0X — будет считать это шестнадцатеричным числом (radix = 16).
  • Всё остальное — десятичное (radix = 10 в современных браузерах)

parseInt(“0x10”); // 16
parseInt(“010”); // 10 — но раньше это парсилось как 8
parseInt(“0b1010”); // 0 — ‘b’ не цифра в десятичной системе

parseInt() не распознаёт 0b и 0o, в отличие от Number(), поэтому эти строки он просто обрежет.

Читает строку символ за символом. Как только parseInt() встречает символ, который не входит в алфавит текущей системы счисления, то сразу останавливается и возвращает то, что успел разобрать:

parseInt("123abc");   // 123
parseInt("1e3");      // 1 — 'e' не цифра
parseInt("2", 2);     // NaN — цифра 2 не существует в двоичной системе

А если в итоге ни одного подходящего символа не нашлось, то возвращается NaN:

parseInt("labubu");   // NaN
parseInt("", 10);    // NaN

Особенности обработки разных форматов

Функция parseInt() может вести себя неожиданно, если не знать нюансы обработки. 

parseInt() никогда не возвращает дробные числа. Даже если в строке есть точка или e, он просто обрежет всё на первом невалидном символе:

parseInt("123.45");  // 123
parseInt("1.9e3");   // 1

В отличие от Number(), parseInt() понимает только 0x как шестнадцатеричный префикс. Остальные (0b, 0o) просто ломают парсинг.

parseInt("0x1f");    // 31
parseInt("0b1010");  // 0
parseInt("0o77");    // 0

Если radix больше 10, parseInt() начинает считать буквы за цифры: a = 10, b = 11, …, z = 35. Регистр не важен.

parseInt("f", 16);       // 15
parseInt("hello", 36);   // 29234652

parseInt() парсит строки и только их. Всё остальное он сначала превращает в строку, а потом обрабатывает слева направо, пока не встретит что-то не то. Поэтому если мы скармливаем ему объекты, булевы значения, undefined и т. д., то результат будет, непредсказуемый.

Например:

parseInt(undefined); // NaN

Массив с одним числом:

parseInt([42]); // 42
// String([42]) → "42" → ок
parseInt([123.45]); // 123
// String([123.45]) → "123.45" → точка обрезается

Системы счисления (radix)

Во фронтенд-разработке мы почти всегда имеем дело с десятичными числами. Но в программировании есть ещё двоичная, восьмеричная, шестнадцатеричная и даже тридцатишестиричная системы. Чтобы parseInt() знал, в какой системе счисления ему читать строку, и нужен параметр radix.

Преобразование в десятичной системе (radix = 10)

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

parseInt("42");    // 42, пока всё ок
parseInt("010");   // 10? 8? 2? — зависит от браузера и года выпуска

Работа с двоичными, восьмеричными и шестнадцатеричными числами

Иногда нужно распарсить строку, где число записано не в десятичной системе. Например, цвет в hex, битовую маску в бинарной или ID в восьмеричной. В таких случаях просто указываем нужное основание (radix):

parseInt("0xFF", 16); // 255 — шестнадцатеричная
parseInt("1010", 2);  // 10  — двоичная
parseInt("77", 8);    // 63  — восьмеричная

parseInt() читает строку в указанной системе счисления и возвращает обычное десятичное число.

Что будет, если не указать radix?

Если radix не указан, parseInt() будет угадывать, что мы имели в виду:

  • Строка начинается с 0x → шестнадцатеричная (radix = 16)
  • Строка начинается с 0 → может быть восьмеричная, может десятичная, зависит от движка и его версии.
  • Всё остальное → десятичное (radix = 10)

До стандарта ES5 строки вроде “010” могли автоматически парситься как восьмеричные. Поэтому в старом IE или Safari parseInt(“010”) возвращал 8. Сейчас такого поведения нет, но для спокойствия всегда указывайте radix = 10.

👉  Если нужно быстро посмотреть, как число выглядит в разных системах счисления, — включите режим «Программист» в стандартном калькуляторе Windows или macOS.

Примеры использования

Простые случаи

Часто parseInt() нужен там, где мы получаем строку, но хотим дальше работать с ней как с числом. Это могут быть данные из localStorage или sessionStorage, дата-атрибутов в HTML (data-*) или API-ответов в формате JSON. Во всех этих случаях числа почти всегда приходят как строки. И если вам нужно посчитать, сравнить или передать их куда-то ещё, то без приведения к числу не обойтись.

Например, мы достаём значение из localStorage. Всё, что там хранится, — строки, даже если туда положили число:

// Преобразуем строку из localStorage в число (кол-во товаров в корзине)
const cartCount = parseInt(localStorage.getItem("cartCount"), 10);

Если не привести данные к числу, cartCount + 1 может превратиться в “31” вместо 4.

Ещё пример: дата-атрибуты. В HTML часто используют data-* для хранения ID, счётчиков и прочей служебной инфы. Но dataset всегда возвращает строки. Если мы передадим этот id в API-запрос, цикл или сравнение, без parseInt() возможны баги.

// Находим кнопку на странице
const btn = document.querySelector("button");
// Берём значение data-id и превращаем в число
const id = parseInt(btn.dataset.id, 10); // "42" → 42

Другой частый кейс — это когда мы получаем JSON-объект с сервера. Даже если по логике age должен быть числом, сервер может вернуть его как строку “29”. Чтобы избежать сюрпризов, парсим.

fetch("/api/user")
  .then(res => res.json())
  .then(data => {
   // Обрабатываем на случай, если вдруг сервер прислал "29" вместо 29
    const age = parseInt(data.age, 10); 
  });

Обработка пользовательского ввода (формы, prompt)

Когда пользователь вводит данные — будь то через форму, инпут или prompt(), — мы почти всегда получаем строку, даже если он ввёл цифру. 

Например:

const input = document.querySelector("#age");
const age = parseInt(input.value, 10)

Здесь мы берём значение из <input type=”text” id=”age”>. Даже если человек ввёл число 42, input.value будет “42”, то есть строка. Без parseInt() мы рискуем получить “42” + 1 → “421”.

prompt() тоже всегда возвращает строку:

const value = prompt("Сколько тебе лет?");
const age = parseInt(value, 10);

Если не проверить и не привести к числу — можно легко поймать NaN или начать складывать строки с числами. Поэтому всегда используйте parseInt() (или parseFloat(), если нужны дроби), когда парсите ввод.

Парсинг CSS-значений (например, «16px»)

Бывает, что при работе с интерфейсом нужно получить числовое значение из CSS — например, узнать какой у элемента padding, каково его положение и font-size, чтобы подогнать размеры иконок, или насколько нужно сдвинуть элемент, чтобы всё выглядело ровно. И чтобы получить фактические стили элементов, используют встроенный метод getComputedStyle():

const style = getComputedStyle(box);

getComputedStyle() возвращает все CSS-свойства элемента, уже с учётом наследования, каскадов и медиазапросов. Но всё это возвращается как строки с единицами: «20px», «1.5em», «75%» и т. д.

console.log(style.paddingLeft); // “20px”

И вот тут как раз нужен parseInt(), чтобы вытащить числовое значение и корректно работать с ним:

// Получаем числовое значение левого отступа
const padding = parseInt(style.paddingLeft, 10); 
// Увеличиваем отступ на 10px и задаём обратно
box.style.paddingLeft = (padding + 10) + "px"; 

Теперь можно спокойно прибавлять, вычитать, передвигать и анимировать. Без parseInt() мы бы получили «20px» + 10 = «20px10» — и CSS нас бы не понял.

Частые ошибки и подводные камни

Неявное преобразование (parseInt(0.000005) → 0)

Допустим, мы передаём сразу число:

parseInt(0.000005);

А в итоге получаем такое:

Почему? Потому что parseInt парсит строки, а не «округляет» числа. 

Несмотря на то что мы передали сразу число, оно всё равно приводится к строке «0.000005». Затем по алгоритму parseInt читает строку слева, натыкается на невалидную точку и обрывает парсинг сразу после первого нуля. В результате мы получаем ноль.

parseInt — инструмент для строк, а не для «обрезания дробей» у уже готовых чисел. Если вы передаёте туда число, то явно делаете что-то не так.

Округление vs парсинг

Некоторые используют parseInt() как способ «откусить» дробную часть:

parseInt(“4.63”); // 4

Вроде бы работает, но parseInt() существует не для этого. Он нужен для парсинга строки, а не для обрезки дробной части числа. Такой подход может привести к багам, особенно если строка пришла в нестандартном формате:

parseInt("4.63px"); // Парсится до первого не-числа
parseInt(4.63);     // Число превращается в строку, потом парсится
parseInt("4.63.9"); // Парсится только первая допустимая часть

Все эти три примера формально работают, но это не значит, что так и надо. Поэтому правильный способ округления — использовать методы Math.floor(), Math.trunc() или Math.round() в зависимости от задачи:

Math.floor(4.63); // округление в меньшую сторону
Math.trunc(4.63); // просто отбрасывает дробную часть
Math.round(4.63); // округление по правилам математики

Разница между parseInt(“08”) и parseInt(“08”, 10)

В современных браузерах оба варианта вернут 8. Потому что по стандарту, если строка не начинается с 0x, parseInt должен использовать десятичную систему счисления.

Но раньше всё было не так. В старых движках ноль в начале строки означал, что число может быть восьмеричным. И тогда:

parseInt("08");  // 0 → 8 недопустима в восьмеричной, парсинг останавливался на 0
parseInt("09");  // 0 → та же история
parseInt("010"); // 8 → восьмеричное 10 = десятичное 8

А вот parseInt(“08”, 10) всегда даст 8, независимо от движка. Поэтому добавление 10 — это хорошая привычка: избавляет от багов в старых браузерах и неожиданных историй с префиксами.

Альтернативы parseInt()

parseInt() — это не единственный способ превратить строку в число. Иногда он даже не самый подходящий: может быть медленнее, может не учитывать дроби или быть просто избыточным. 

Когда использовать Number()

Number() — быстрый и простой способ преобразования, который работает для большинства случаев. Если вы уверены, что строка содержит только число, без суффиксов типа «px», «abc», « », то используйте Number():

Number("12.5");      // 12.5
Number("  100  ");   // 100 — пробелы нормально обрабатываются
Number("42px");      // NaN

Подходит для JSON-данных, если числа туда приходят как строки, значений из input[type=”number”] и localStorage.

parseFloat() для дробных чисел

Если parseInt() выдёргивает из строки целую часть, то parseFloat() умеет парсить и дроби. Причём работает по тому же принципу — идёт слева направо, пока не наткнётся на что-то непонятное, и берёт всё, что похоже на число с точкой.

parseFloat("3.14");      // 3.14
parseFloat("3.14px");    // 3.14
parseFloat("42.0%")      // 42
parseFloat("hello");     // NaN

Иногда результат может быть Infinity — если, например, передали что-то слишком большое:

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

Современный способ: + и Number.parseInt()

В повседневной разработке обычно хватает двух приёмов: унарного плюса и Number.parseInt(). Оба удобны, просто работают и подходят для разных задач.

Унарный плюс — это короткий и быстрый способ привести значение к числу. Особенно хорошо работает в ситуациях, где мы ожидаем чистое число, — например, при работе с формами, API или данными из JSON. Если в строке окажется что-то лишнее, результатом будет NaN — и это хорошо, потому что сразу видно, что что-то пошло не так.

Например, здесь мы получаем количество товаров из пользовательского ввода — значение из текстового поля возвращается как строка, поэтому применяем унарный +, чтобы сразу превратить его в число:

const qty = +document.querySelector(‘#qty’).value.trim();

А в этом примере мы преобразуем цену, полученную из API. Часто бэкенд присылает числовые значения в виде строк — унарный плюс быстро превращает их в числа, с которыми можно работать:

const total = +response.total; // “1999.50” → 1999.5

Важный момент: если мы передаём пустую строку, то она превращается в 0:

+” // 0

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

// Извлекаем числовое значение из строки с текстовым суффиксом
Number.parseInt('16px', 10);     // 16
Number.parseInt('  -100%', 10);  // -100
// Работаем с разными системами счисления
Number.parseInt('ff', 16);       // 255
Number.parseInt('1010', 2);      // 10

Зачем писать Number.parseInt(), если всё то же самое? Так проще читать: видно, что мы парсим число, и сразу понятно, что здесь не просто глобальная функция, а работа с числами. Ещё это хороший способ приучить себя всегда указывать основание radix, что снижает возможность багов.

Вам слово

Приходите к нам в соцсети поделиться своим мнением о статье и почитать, что пишут другие. А ещё там выходит дополнительный контент, которого нет на сайте — шпаргалки, опросы и разная дурка. В общем, вот тележка, вот ВК — велком!

Обложка:

Алексей Сухов

Корректор:

Александр Зубов

Вёрстка:

Мария Климентьева

Соцсети:

Юлия Зубарева

Вам может быть интересно
easy
[anycomment]
Exit mobile version