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。
评论
<code>
标签,对于多行,请将其包装在<pre>
标签中,对于超过 10 行的内容,请使用沙盒(plnkr、jsbin、codepen…)