Spec-Zone.ru › JavaScript

BigInt

Базовая линия Широко доступно

Эта функция хорошо зарекомендовала себя и работает на многих устройствах и версиях браузеров. Она доступна в браузерах с сентября 2020 года.

BigInt значения представляют целочисленные значения, которые слишком высоки или слишком низки для представления number примитивным значением.

Описание

Значение BigInt, также иногда называемое просто BigInt, представляет собой bigint примитивное значение, создаваемое путем добавления n в конце целочисленного литерала или путем вызова функции BigInt() (без оператора new) и передачи ей целочисленного значения или строкового значения.

const previouslyMaxSafeInteger = 9007199254740991n;

const alsoHuge = BigInt(9007199254740991);
// 9007199254740991n

const hugeString = BigInt("9007199254740991");
// 9007199254740991n

const hugeHex = BigInt("0x1fffffffffffff");
// 9007199254740991n

const hugeOctal = BigInt("0o377777777777777777");
// 9007199254740991n

const hugeBin = BigInt(
  "0b11111111111111111111111111111111111111111111111111111",
);
// 9007199254740991n

Значения BigInt некоторым образом похожи на значения Number, но также отличаются в нескольких ключевых моментах: Значение BigInt нельзя использовать с методами встроенного объекта Math, и его нельзя смешивать со значением Number в операциях; они должны быть приведены к одному типу. Однако будьте осторожны при преобразовании значений туда и обратно, так как точность значения BigInt может быть потеряна при его преобразовании в значение Number.

Информация о типе

При проверке с помощью typeof, значение BigInt (bigint примитив) даст "bigint":

typeof 1n === "bigint"; // true
typeof BigInt("1") === "bigint"; // true

Значение BigInt также можно обернуть в Object:

typeof Object(1n) === "object"; // true

Операторы

Большинство операторов поддерживают BigInt, однако большинство не допускают операнды смешанных типов — оба операнда должны быть BigInt или ни один:

  • Арифметические операторы: +, -, *, /, %, **
  • Побитовые операторы: >>, <<, &, |, ^, ~
  • Унарное отрицание (-)
  • Инкремент/декремент: ++, --

Операторы, возвращающие булево значение, допускают смешивание чисел и BigInt в качестве операндов:

  • Относительные операторы и операторы равенства: >, <, >=, <=, ==, !=, ===, !==
  • Логические операторы опираются только на истинность операндов

Несколько операторов вообще не поддерживают BigInt:

  • Унарный плюс (+) не может быть поддержан из-за конфликтующего использования в asm.js, поэтому он был исключен чтобы не нарушать asm.js.
  • Беззнаковый сдвиг вправо (>>>) — единственный побитовый оператор, который не поддерживается, поскольку любое значение BigInt является знаковым.

Особые случаи:

  • Сложение (+) строки и BigInt возвращает строку.
  • Деление (/) отбрасывает дробные части по направлению к нулю, поскольку BigInt не может представлять дробные величины.
const previousMaxSafe = BigInt(Number.MAX_SAFE_INTEGER); // 9007199254740991n
const maxPlusOne = previousMaxSafe + 1n; // 9007199254740992n
const theFuture = previousMaxSafe + 2n; // 9007199254740993n, this works now!
const prod = previousMaxSafe * 2n; // 18014398509481982n
const diff = prod - 10n; // 18014398509481972n
const mod = prod % 10n; // 2n
const bigN = 2n ** 54n; // 18014398509481984n
bigN * -1n; // -18014398509481984n
const expected = 4n / 2n; // 2n
const truncated = 5n / 2n; // 2n, not 2.5n

Сравнения

Значение BigInt не строго равно значению Number, но оно *является* приблизительно равным:

0n === 0; // false
0n == 0; // true

Значение Number и значение BigInt могут быть сравнены как обычно:

1n < 2; // true
2n > 1; // true
2 > 2; // false
2n > 2; // false
2n >= 2; // true

Значения BigInt и Number могут быть смешаны в массивах и отсортированы:

const mixed = [4n, 6, -12n, 10, 4, 0, 0n];
// [4n, 6, -12n, 10, 4, 0, 0n]

mixed.sort(); // default sorting behavior
// [ -12n, 0, 0n, 10, 4n, 4, 6 ]

mixed.sort((a, b) => a - b);
// won't work since subtraction will not work with mixed types
// TypeError: can't convert BigInt value to Number value

// sort with an appropriate numeric comparator
mixed.sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));
// [ -12n, 0, 0n, 4n, 4, 6, 10 ]

Обратите внимание, что сравнения со значениями BigInt, обернутыми в Object, ведут себя как с другими объектами, указывая на равенство только при сравнении одной и той же инстанции объекта:

Object(0n) === 0n; // false
Object(0n) === Object(0n); // false

const o = Object(0n);
o === o; // true

Поскольку преобразование между значениями Number и BigInt может привести к потере точности, рекомендуется следующее:

  • Используйте значение BigInt только тогда, когда ожидаются значения больше 253.
  • Не преобразуйте между значениями BigInt и Number.

Условные выражения

Значение BigInt следует тем же правилам преобразования, что и Number, когда:

  • оно преобразуется в Boolean: через функцию Boolean;
  • при использовании с логическими операторами ||, && и !; или
  • внутри условного теста, такого как if инструкция.

А именно, только 0n является ложью; все остальное является истиной.

if (0n) {
  console.log("Hello from the if!");
} else {
  console.log("Hello from the else!");
}
// "Hello from the else!"

0n || 12n; // 12n
0n && 12n; // 0n
Boolean(0n); // false
Boolean(12n); // true
!12n; // false
!0n; // true

Криптография

Операции, поддерживаемые для значений BigInt, не имеют постоянного времени выполнения и поэтому подвержены атакам по времени. Поэтому JavaScript BigInts могут быть опасны для использования в криптографии без смягчающих факторов. В качестве очень общего примера злоумышленник может измерить разницу во времени между 101n ** 65537n и 17n ** 9999n и определить величину секретов, таких как закрытые ключи, на основе прошедшего времени. Если вам все же приходится использовать BigInts, ознакомьтесь с FAQ по атакам по времени для общих советов по данной проблеме.

Использование в JSON

Использование JSON.stringify() с любым значением BigInt вызовет TypeError, так как значения BigInt по умолчанию не сериализуются в JSON. Однако JSON.stringify() специально оставляет лазейку для значений BigInt: он попытается вызвать метод BigInt'а toJSON(). (Он не делает этого для каких-либо других примитивных значений.) Следовательно, вы можете реализовать свой собственный метод toJSON() (что является одним из немногих случаев, когда патчинг встроенных объектов явно не поощряется):

BigInt.prototype.toJSON = function () {
  return { $bigint: this.toString() };
};

Вместо выбрасывания ошибки, JSON.stringify() теперь выдает строку, подобную этой:

console.log(JSON.stringify({ a: 1n }));
// {"a":{"$bigint":"1"}}

Если вы не хотите патчить BigInt.prototype, вы можете использовать параметр replacer функции JSON.stringify для сериализации значений BigInt:

const replacer = (key, value) =>
  typeof value === "bigint" ? { $bigint: value.toString() } : value;

const data = {
  number: 1,
  big: 18014398509481982n,
};
const stringified = JSON.stringify(data, replacer);

console.log(stringified);
// {"number":1,"big":{"$bigint":"18014398509481982"}}

Затем вы можете использовать параметр reviver функции JSON.parse для их обработки:

const reviver = (key, value) =>
  value !== null &&
  typeof value === "object" &&
  "$bigint" in value &&
  typeof value.$bigint === "string"
    ? BigInt(value.$bigint)
    : value;

const payload = '{"number":1,"big":{"$bigint":"18014398509481982"}}';
const parsed = JSON.parse(payload, reviver);

console.log(parsed);
// { number: 1, big: 18014398509481982n }

Примечание: Хотя можно сделать replacer функции JSON.stringify() универсальным и правильно сериализовать значения BigInt для всех объектов, как показано выше, reviver функции JSON.parse() следует использовать с осторожностью, поскольку сериализация *необратима*: невозможно отличить объект, который случайно имеет свойство с именем $bigint, от фактического BigInt.

Кроме того, приведенный выше пример создает весь объект при замене и восстановлении, что может иметь последствия для производительности или хранения для больших объектов, содержащих много BigInt. Если вы знаете структуру полезной нагрузки, может быть лучше просто сериализовать их как строки и восстанавливать на основе имени ключа свойства.

Фактически, JSON допускает числовые литералы произвольной длины; они просто не могут быть разобраны с полной точностью в JavaScript. Если вы общаетесь с другой программой на языке, который поддерживает более длинные целые числа (такие как 64-битные целые числа), и вы хотите передать BigInt как число JSON, а не как строку JSON, см. Lossless number serialization.

Приведение BigInt

Многие встроенные операции, ожидающие BigInts, сначала приводят свои аргументы к BigInts. Операция может быть суммирована следующим образом:

  • BigInts возвращаются как есть.
  • undefined и null вызывают TypeError.
  • true превращается в 1n; false превращается в 0n.
  • Строки преобразуются путем их парсинга, как если бы они содержали целочисленный литерал. Любой сбой парсинга приводит к SyntaxError. Синтаксис является подмножеством строковых числовых литералов, где десятичные точки или индикаторы экспоненты не допускаются.
  • Числа вызывают TypeError для предотвращения непреднамеренного неявного приведения, приводящего к потере точности.
  • Символы вызывают TypeError.
  • Объекты сначала преобразуются в примитив путем вызова их методов [Symbol.toPrimitive]() (с "number" в качестве подсказки), valueOf() и toString(), в таком порядке. Полученный примитив затем преобразуется в BigInt.

Лучший способ добиться почти такого же эффекта в JavaScript — это функция BigInt(): BigInt(x) использует тот же алгоритм для преобразования x, за исключением того, что числа не вызывают TypeError, а преобразуются в BigInts, если они являются целыми числами.

Обратите внимание, что встроенные операции, ожидающие BigInts, часто усекают BigInt до фиксированной ширины после приведения. Это включает BigInt.asIntN(), BigInt.asUintN(), а также методы BigInt64Array и BigUint64Array.

Конструктор

BigInt()
Возвращает примитивные значения типа BigInt. Вызывает ошибку при вызове с new.

Статические методы

BigInt.asIntN()
Усекает значение BigInt до заданного количества младших битов и возвращает это значение как знаковое целое число.
BigInt.asUintN()
Усекает значение BigInt до заданного количества младших битов и возвращает это значение как беззнаковое целое число.

Свойства экземпляра

Эти свойства определены на BigInt.prototype и разделяются всеми экземплярами BigInt.

BigInt.prototype.constructor
Конструкторная функция, создавшая объект экземпляра. Для экземпляров BigInt начальное значение — конструктор BigInt.
BigInt.prototype[Symbol.toStringTag]
Начальное значение свойства [Symbol.toStringTag] — строка "BigInt". Это свойство используется в Object.prototype.toString(). Однако, поскольку BigInt также имеет собственный метод toString(), это свойство не используется, если вы не вызовете Object.prototype.toString.call() с BigInt в качестве thisArg.

Методы экземпляра

BigInt.prototype.toLocaleString()
Возвращает строку с локализованным представлением этого значения BigInt. Переопределяет метод Object.prototype.toLocaleString().
BigInt.prototype.toString()
Возвращает строку, представляющую это значение BigInt в указанной системе счисления (основании). Переопределяет метод Object.prototype.toString().
BigInt.prototype.valueOf()
Возвращает это значение BigInt. Переопределяет метод Object.prototype.valueOf().

Примеры

Вычисление простых чисел

function isPrime(n) {
  if (n < 2n) {
    return false;
  }
  if (n % 2n === 0n) {
    return n === 2n;
  }
  for (let factor = 3n; factor * factor <= n; factor += 2n) {
    if (n % factor === 0n) {
      return false;
    }
  }
  return true;
}

// Takes a BigInt value as an argument, returns nth prime number as a BigInt value
function nthPrime(nth) {
  let maybePrime = 2n;
  let prime = 0n;

  while (nth >= 0n) {
    if (isPrime(maybePrime)) {
      nth--;
      prime = maybePrime;
    }
    maybePrime++;
  }

  return prime;
}

nthPrime(20n);
// 73n

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

Спецификации

Спецификация
ECMAScript® 2027 Language Specification
# sec-bigint-objects

Совместимость с браузерами

Настольные Мобильные Сервер
Chrome Edge Firefox Opera Safari Chrome Android Firefox for Android Opera Android Safari on iOS Samsung Internet WebView Android WebView on iOS Bun Deno Node.js
BigInt
67
79
68
54
14
67
68
48
14
9.0
67
14
1.0.0
1.0
10.4.0
BigInt
67
79
68
54
14
67
68
48
14
9.0
67
14
1.0.0
1.0
10.4.0
asIntN
67
79
68
54
14
67
68
48
14
9.0
67
14
1.0.0
1.0
10.4.0
asUintN
67
79
68
54
14
67
68
48
14
9.0
67
14
1.0.0
1.0
10.4.0
toLocaleString
67
79
68
54
14
67
68
48
14
9.0
67
14
1.0.0
1.0
10.4.0
toString
67
79
68
54
14
67
68
48
14
9.0
67
14
1.0.0
1.0
10.4.0
valueOf
67
79
68
54
14
67
68
48
14
9.0
67
14
1.0.0
1.0
10.4.0

См. также

  • Number
  • Number.MAX_SAFE_INTEGER

© 2005–2025 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API