2020 年 9 月 21 日

BigInt

最近添加
这是最近添加到该语言中的内容。你可以在 https://caniuse.cn/#feat=bigint 找到当前支持状态。

BigInt 是一种特殊数字类型,它提供对任意长度整数的支持。

可以通过在整数文本末尾追加 n 来创建大整数,或者通过调用函数 BigInt 来创建大整数,该函数从字符串、数字等创建大整数。

const bigint = 1234567890123456789012345678901234567890n;

const sameBigint = BigInt("1234567890123456789012345678901234567890");

const bigintFromNumber = BigInt(10); // same as 10n

数学运算符

BigInt 通常可以像常规数字一样使用,例如

alert(1n + 2n); // 3

alert(5n / 2n); // 2

请注意:除法 5/2 返回的结果是四舍五入为零,没有小数部分。对大整数执行的所有运算都会返回大整数。

我们不能混合大整数和常规数字

alert(1n + 2); // Error: Cannot mix BigInt and other types

如果需要,我们应该显式转换它们:使用 BigInt()Number(),如下所示

let bigint = 1n;
let number = 2;

// number to bigint
alert(bigint + BigInt(number)); // 3

// bigint to number
alert(Number(bigint) + number); // 3

转换操作始终是静默的,从不报错,但如果大整数太大而不适合数字类型,那么多余的位将被截断,因此我们应该小心进行这样的转换。

大整数不支持一元加号

一元加号运算符 +value 是将 value 转换为数字的众所周知的方法。

为了避免混淆,大整数不支持它

let bigint = 1n;

alert( +bigint ); // error

因此,我们应该使用 Number() 将大整数转换为数字。

比较

比较,例如 <> 可以很好地处理大整数和数字

alert( 2n > 1n ); // true

alert( 2n > 1 ); // true

但请注意,由于数字和大整数属于不同的类型,它们可以相等 ==,但不能严格相等 ===

alert( 1 == 1n ); // true

alert( 1 === 1n ); // false

布尔运算

if 或其他布尔运算中,大整数的行为与数字类似。

例如,在 if 中,大整数 0n 为假,其他值为真

if (0n) {
  // never executes
}

布尔运算符,例如 ||&& 等也与数字类似,适用于大整数

alert( 1n || 2 ); // 1 (1n is considered truthy)

alert( 0n || 2 ); // 2 (0n is considered falsy)

Polyfill

Polyfill 大整数很棘手。原因在于许多 JavaScript 运算符,例如 +- 等,与常规数字相比,在大整数上的行为不同。

例如,大整数的除法始终返回大整数(必要时四舍五入)。

为了模拟这种行为,Polyfill 需要分析代码并将所有此类运算符替换为其函数。但这样做很麻烦,而且会消耗大量性能。

因此,没有公认的良好 Polyfill。

不过,JSBI 库的开发者提出了相反的方式。

此库使用自己的方法实现大数字。我们可以使用它们来代替本机大整数

操作 本机 BigInt JSBI
从数字创建 a = BigInt(789) a = JSBI.BigInt(789)
加法 c = a + b c = JSBI.add(a, b)
减法 c = a - b c = JSBI.subtract(a, b)

…然后使用填充(Babel 插件)将 JSBI 调用转换为原生 BigInt,适用于支持它们的浏览器。

换句话说,这种方法建议我们在 JSBI 中编写代码,而不是原生 BigInt。但 JSBI 在内部将数字当作 BigInt 使用,紧密遵循规范模拟它们,因此代码将“准备好 BigInt”。

对于不支持 BigInt 的引擎,我们可以“按原样”使用此类 JSBI 代码,对于支持 BigInt 的引擎,填充将调用转换为原生 BigInt。

参考

教程地图

评论

在评论之前阅读此内容…
  • 如果您有改进建议,请提交 GitHub 问题或提交拉取请求,而不是评论。
  • 如果您无法理解文章中的某些内容,请详细说明。
  • 要插入几行代码,请使用 <code> 标签,对于多行,请将其包装在 <pre> 标签中,对于超过 10 行的内容,请使用沙盒(plnkrjsbincodepen…)