Числа и Math в JavaScript #
Число в JavaScript — значение типа number: целые, дробные, NaN и бесконечности хранятся в одном типе по стандарту IEEE 754 (64-битное с плавающей точкой). Для цен, скидок, ETA доставки и игровых очков этого достаточно; для очень больших целых есть отдельный тип bigint.
Литералы и базовые операции #
const itemPrice = 490
const quantity = 3
const lineTotal = itemPrice * quantity // 1470
const discountRate = 0.15
const discounted = lineTotal * (1 - discountRate) // 1249.5
const hexColor = 0xff6600 // 16737792 — шестнадцатеричная запись
const binaryFlag = 0b1010 // 10
Деление всегда даёт число с плавающей точкой:
10 / 4 // 2.5
7 / 2 // 3.5
Остаток от деления — оператор %:
const minutes = 73
const hours = Math.floor(minutes / 60) // 1
const rest = minutes % 60 // 13 — «осталось 13 минут»
NaN, Infinity и проверки #
NaN («Not a Number») появляется, когда арифметика не может дать осмысленный результат:
Number('checkout') // NaN
0 / 0 // NaN
NaN не равен сам себе — сравнивайте через Number.isNaN:
NaN === NaN // false
Number.isNaN(NaN) // true
Number.isNaN('x') // false — не приводит аргумент
Infinity и -Infinity — результат переполнения или деления на ноль:
1 / 0 // Infinity
-1 / 0 // -Infinity
Для «нормальных» конечных чисел удобен Number.isFinite:
Number.isFinite(42) // true
Number.isFinite(Infinity) // false
Number.isFinite('42') // false — строка не число
Точность и округление #
Двоичное представление не всегда точно для десятичных дробей:
0.1 + 0.2 // 0.30000000000000004
В интерфейсе корзины показывайте сумму через форматирование, а не «сырое» сложение:
const subtotal = 0.1 + 0.2
subtotal.toFixed(2) // "0.30" — строка для отображения
const displayTotal = Math.round(subtotal * 100) / 100 // 0.3 — число
toFixed(n) возвращает строку с n знаками после запятой:
(1490.5).toFixed(0) // "1491"
(12.345).toFixed(2) // "12.35"
Math.round, Math.floor, Math.ceil, Math.trunc — разные стратегии округления:
const deliveryFee = 89.7
Math.round(deliveryFee) // 90
Math.floor(deliveryFee) // 89
Math.ceil(deliveryFee) // 90
Math.trunc(-3.9) // -3
parseInt, parseFloat и Number #
Строки из форм и API часто нужно превратить в число:
parseInt('150₽', 10) // 150 — читает с начала, основание 10 обязательно
parseFloat('3.14 кг') // 3.14
Number(' 42 ') // 42 — вся строка должна быть числом
Number('42px') // NaN
Унарный + — краткий аналог Number:
const rawQty = '2'
const qty = +rawQty // 2
Для пользовательского ввода надёжнее явная функция с запасным значением:
function toCartQuantity(value, fallback = 1) {
const n = Number(value)
if (!Number.isInteger(n) || n < 1) return fallback
return n
}
toCartQuantity('3') // 3
toCartQuantity('0') // 1
toCartQuantity('abc') // 1
Объект Math #
Math — встроенный набор математических функций и констант (не конструктор):
Math.PI // 3.141592653589793
Math.abs(-17) // 17
Math.max(10, 3, 88) // 88
Math.min(...[490, 320, 150]) // 150
Math.pow(2, 10) // 1024 — то же, что 2 ** 10
Math.sqrt(144) // 12
Случайное число в диапазоне [min, max):
function randomScore(min, max) {
return Math.floor(Math.random() * (max - min)) + min
}
randomScore(1, 101) // целое от 1 до 100 включительно при max = 101
Округление до шага (например, скидка кратно 50 ₽):
function roundToStep(amount, step) {
return Math.round(amount / step) * step
}
roundToStep(1249, 50) // 1250
BigInt #
Если целое не помещается в безопасный диапазон Number (Number.MAX_SAFE_INTEGER — 9007199254740991), используйте bigint с суффиксом n:
const bigOrderId = 9007199254740992n
bigOrderId + 1n // 9007199254740993n
// bigOrderId + 1 — TypeError: нельзя смешивать bigint и number
BigInt не подходит для дробей и не смешивается с number в одной операции без явного приведения.
Сравнение и особые значения #
const scoreA = 100
const scoreB = '100'
scoreA == scoreB // true — неявное приведение
scoreA === scoreB // false — разные типы
Object.is(0, -0) // false
Object.is(NaN, NaN) // true — в отличие от ===
Для денег и количества в коде предпочитайте === и заранее нормализованные числа (см. Преобразование типов).
Практика: итог корзины #
const cartLines = [
{ sku: 'kb-01', price: 490, qty: 1 },
{ sku: 'ms-02', price: 1290, qty: 2 },
]
function cartSubtotal(lines) {
return lines.reduce((sum, line) => sum + line.price * line.qty, 0)
}
function applyDeliveryFee(subtotal, freeFrom = 3000, fee = 199) {
return subtotal >= freeFrom ? 0 : fee
}
const subtotal = cartSubtotal(cartLines) // 3070
const delivery = applyDeliveryFee(subtotal)
const total = subtotal + delivery
`${total.toFixed(2)} ₽` // "3269.00 ₽" при fee = 199
Итог #
- В JS один числовой тип
number(плюсbigintдля огромных целых). NaNиInfinity— особые значения; проверяйте черезNumber.isNaNиNumber.isFinite.- Дробная арифметика может давать артефакты — форматируйте вывод через
toFixedили целые копейки. parseInt/parseFloatтерпимы к «хвосту» в строке;Number— строже.Mathдаёт округление, min/max, степени и псевдослучайность без подключения библиотек.