BigInt
BigInt — примитивный тип для работы с целыми числами произвольной длины, без ограничения Number.MAX_SAFE_INTEGER.
Зачем нужно
Number точно представляет целые числа только до 2^53 - 1 (9 007 199 254 740 991). Для ID из баз данных, криптографии, финансовых расчётов с большими суммами нужен BigInt.
Где используется
- ID из баз данных (Snowflake ID в Twitter/Discord)
- Криптографические вычисления
- Точные финансовые расчёты с большими числами
- Работа с timestamp в наносекундах
Предпосылки
Создание BigInt
// Литерал — суффикс n
const big = 9007199254740991n;
const huge = 123456789012345678901234567890n;
// Функция BigInt
const fromNumber = BigInt(42); // 42n
const fromString = BigInt('9007199254740991'); // 9007199254740991n
// BigInt НЕ конструктор
// const x = new BigInt(42); // TypeError!
// Проблема Number
console.log(9007199254740991 + 1); // 9007199254740992
console.log(9007199254740991 + 2); // 9007199254740992 — потеря!
// BigInt точен
console.log(9007199254740991n + 1n); // 9007199254740992n
console.log(9007199254740991n + 2n); // 9007199254740993n — точно!
Операции
const a = 100n;
const b = 30n;
// Арифметика
a + b; // 130n
a - b; // 70n
a * b; // 3000n
a / b; // 3n (целочисленное деление, дробная часть отбрасывается!)
a % b; // 10n
a ** 3n; // 1000000n
// Сравнение
10n === 10n; // true
10n === 10; // false (разные типы!)
10n == 10; // true (нестрогое сравнение)
10n > 5; // true (сравнение с Number работает)
10n < 20; // true
// Унарные
-10n; // -10n
// +10n; // TypeError! Унарный + не поддерживается
// Логические
!0n; // true (0n — falsy)
!1n; // false (1n — truthy)
Ограничения
// Нельзя смешивать с Number в арифметике
// 10n + 5; // TypeError: Cannot mix BigInt and other types
// Решение: явное преобразование
10n + BigInt(5); // 15n
Number(10n) + 5; // 15 (может потерять точность!)
// Нельзя использовать с Math
// Math.sqrt(4n); // TypeError
// Нельзя использовать дробные числа
// BigInt(1.5); // RangeError
// JSON.stringify не поддерживает BigInt
// JSON.stringify({ id: 42n }); // TypeError
// Решение для JSON
const data = { id: 42n };
JSON.stringify(data, (key, value) =>
typeof value === 'bigint' ? value.toString() : value
); // '{"id":"42"}'
Практическое применение
ID из базы данных
// Snowflake ID (Discord, Twitter) не влезает в Number
const discordId = '1234567890123456789';
console.log(Number(discordId)); // 1234567890123456800 — потеря!
console.log(BigInt(discordId)); // 1234567890123456789n — точно
// Работа с API
async function getUser(id) {
// Передаём как строку в URL
const response = await fetch(`/api/users/${id.toString()}`);
const data = await response.json();
// Парсим обратно
data.id = BigInt(data.id);
return data;
}
Факториал больших чисел
function factorial(n) {
let result = 1n;
for (let i = 2n; i <= n; i++) {
result *= i;
}
return result;
}
console.log(factorial(50n));
// 30414093201713378043612608166979581188299763898377856820553615673507270386838265
// Number не смог бы это представить
Частые ошибки
1. Смешивание типов
// const result = 10n + 5; // TypeError
const result = 10n + BigInt(5); // 15n
2. Деление отбрасывает дробь
console.log(7n / 2n); // 3n (не 3.5n!)
3. JSON сериализация
// Добавь toJSON в прототип или используй replacer
BigInt.prototype.toJSON() = function {
return this.toString();
};
Практика
- Вычисли
2n ** 100nи убедись, что Number не справляется - Напиши функцию факториала для BigInt
- Реализуй безопасный парсинг больших ID из JSON-строки
Связанные темы
Ресурсы
🎓 Источник: 💻 Новое в JavaScript ES.Next, ES2020...ES6
- 📅 2019-12-03 · YouTube
- Тезисы: BigInt появился в ES2020. Литерал
nсуффикс. Нельзя смешивать с Number в одной операции — TypeError. JSON не умеет BigInt — нужен toString