Числа в JavaScript
JavaScript поддерживает различные типы чисел. Понимание чисел в JS важно для эффективного написания кода. Узнайте о типах, округлении и преобразовании.
Введение в числа JavaScript
JavaScript — динамический язык, и способ хранения чисел напрямую влияет на повседневный код: почему 0.1 + 0.2 не равно точно 0.3, почему очень большие целые числа теряют точность, и как безопасно округлять, форматировать и разбирать значения. На этой странице рассматриваются обычный тип number, специальные значения Infinity и NaN, функции преобразования и подводные камни, с которыми сталкивается большинство разработчиков, — с запускаемыми примерами, которые можно редактировать.
Понимание числовых типов
В JavaScript есть ровно два числовых типа данных:
number— повседневный тип. Использует 64-битный формат IEEE-754 («числа с плавающей точкой двойной точности»), поэтому один и тот же тип хранит как целые числа вроде42, так и десятичные дроби вроде3.14. Отдельных типовintилиfloatнет.BigInt— для целых чисел, выходящих за пределы безопасного диапазонаnumber(подробнее ниже). Литерал BigInt заканчивается наn, например9007199254740993n.
Их можно различить с помощью typeof:
Запись чисел в JavaScript
Помимо обычных цифр, JavaScript предлагает несколько удобных способов для удобочитаемости:
let billion = 1e9; // scientific notation → 1000000000
let ms = 1e-6; // 0.000001 (one microsecond)
let big = 1_000_000; // underscores as visual separators (ES2021)1e9 означает «1, за которой следуют 9 нулей»; 1e-6 означает «сдвинуть десятичную запятую на 6 позиций влево». Символы подчёркивания в 1_000_000 игнорируются движком — они лишь помогают людям читать большие числа.
Шестнадцатеричные, двоичные и восьмеричные числа
JavaScript умеет читать литералы в нескольких системах счисления. Все они хранятся как один и тот же тип number — различается только запись:
let hex = 0xFF; // 255 (base 16, prefix 0x)
let bin = 0b1010; // 10 (base 2, prefix 0b)
let oct = 0o744; // 484 (base 8, prefix 0o)Метод toString
num.toString(base) преобразует число в строку в любой системе счисления от 2 до 36 — это операция, обратная описанным выше литералам:
Примечание: чтобы вызвать метод непосредственно на литерале, нужны две точки или скобки — 255..toString(16) или (255).toString(16) — потому что 255. воспринимается как десятичная точка.
Методы округления
JavaScript предоставляет несколько функций для округления чисел:
Math.floor(): Округляет число вниз до ближайшего целого.
Math.ceil(): Округляет число вверх до ближайшего целого.
Math.round(): Округляет число до ближайшего целого по стандартным математическим правилам.
Math.trunc(): Удаляет дробную часть, фактически усекая число.
Разница между Math.floor и Math.trunc проявляется только с отрицательными числами: Math.floor(-3.5) равно -4 (округление в сторону -Infinity), тогда как Math.trunc(-3.5) равно -3 (просто отбрасывает дробную часть). Другие методы округления и математические вспомогательные функции описаны в главе JavaScript Math.
Форматирование чисел: toFixed и toPrecision
Когда нужно получить число в виде строки с фиксированным форматом — деньги, проценты, отчёты — используйте эти методы вместо Math.round:
toFixed(digits)сохраняет фиксированное количество цифр после десятичной точки.toPrecision(digits)сохраняет фиксированное количество значимых цифр.
Оба метода возвращают строки. Оберните результат в Number(), если нужно снова получить число. toLocaleString() — лучший выбор для разделителей тысяч и отображения валюты в соответствии с локалью пользователя.
Неточные вычисления
Поскольку тип number использует двоичную плавающую точку, некоторые десятичные дроби не могут быть сохранены точно — знаменитое 0.1 + 0.2 !== 0.3. Это не ошибка JavaScript; такое поведение есть в каждом языке, поддерживающем IEEE-754.
Практическое правило: никогда не сравнивайте результаты операций с плавающей точкой с помощью ===. Либо сначала округлите оба значения, либо проверьте, что их разность меньше Number.EPSILON (наименьший промежуток между 1 и следующим представимым числом).
Безопасные целые числа
Тип number может точно хранить целые числа лишь до Number.MAX_SAFE_INTEGER (2^53 − 1). За этим пределом два разных целых числа могут схлопнуться в одно значение:
Если вы работаете с ID, временными метками в наносекундах или большими счётчиками, превышающими этот предел, переходите на BigInt.
Специальные числовые значения
Понимание Infinity, -Infinity и NaN в JavaScript:
- Infinity: Представляет бесконечность — значение, большее любого другого числа. Это результат деления числа на ноль или превышения верхней границы чисел с плавающей точкой.
- -Infinity: Представляет отрицательную бесконечность — значение, меньшее любого другого числа. Возникает при делении отрицательного числа на ноль или выходе за нижнюю границу чисел с плавающей точкой.
- NaN: Расшифровывается как «Not-a-Number» (не число). Это значение является результатом неопределённой или невыражаемой математической операции, например деления нуля на ноль.
Методы isNaN() и isFinite() для проверки этих специальных значений:
isNaN(): Проверяет, является ли значениеNaN. Обратите внимание: глобальныйisNaN()выполняет неявное приведение типов, поэтомуisNaN('hello')возвращаетtrue. Для строгой проверки типов используйтеNumber.isNaN(), который возвращаетtrueтолько если значение действительно равноNaN.isFinite(): Проверяет, является ли значение конечным числом, возвращаяfalseдляInfinity,-InfinityилиNaN.
Примеры:
isNaN('hello')возвращаетtrue, потому что строка приводится кNaN.isFinite(2 / 0)возвращаетfalse, так как2 / 0даётInfinity, а оно не является конечным числом.
Числовое преобразование: Number(), parseInt и parseFloat
Существуют три распространённых способа преобразовать string в число, и правильный выбор имеет значение.
Number(value) строг: вся строка должна быть допустимым числом (пробельные символы обрезаются), иначе возвращается NaN. Пустая строка превращается в 0.
parseInt(value, radix) снисходительнее: он читает строку слева и останавливается на первом символе, который не является частью целого числа. Если первый символ не может быть разобран, возвращается NaN. Всегда передавайте radix (основание системы счисления), чтобы избежать сюрпризов.
parseFloat(value) работает как parseInt, но понимает десятичную точку и читает строку до тех пор, пока не встретит символ, который не является частью числа с плавающей точкой:
Практическое правило: используйте Number(), когда строка должна быть полностью числовой (например, при валидации ввода формы), и parseInt/parseFloat, когда нужно извлечь число из текста вроде '100px'.
Заключение
JavaScript хранит все обычные числа как 64-битные значения с плавающей точкой, что объясняет особенности округления, ограничение безопасных целых чисел и необходимость осторожного форматирования и сравнения. Понимание того, когда применять toFixed, Number.EPSILON, BigInt или parseInt, позволяет писать предсказуемо работающий код. Продолжайте изучение со связанными руководствами по типам: Строки, BigInt, объект Math и Типы данных.