「这是我参与11月更文挑战的第9天,活动详情查看:2021最后一次更文挑战」
前言
在 JavaScript Number类型的数据存在最大的安全整数 2^53 - 1
,当我们的项目需要的数字很大的时候,会出现一些莫名其妙的问题。
const max = 2**53
console.log(max === max+1) // true
const num = 9007199254740993
console.log(num) // 9007199254740992
所以如果想要突破这个最大安全整数,我们可以使用 BigInt
数据类型,他可以表示任意大的整数。
定义
定义一BigInt类型,可以用在一个整数字面量后面加 n
的方式定义 ,如:10n
,或者调用函数BigInt()
。
const num = 9007199254740993n;
console.log(num); // 9007199254740993n
// 十进制
const hugeString = BigInt("9007199254740991"); // ↪ 9007199254740991n
// 十六进制
const hugeHex = BigInt("0x1fffffffffffff");
// 二进制
const hugeBin = BigInt("0b11111111111111111111111111111111111111111111111111111");
// ↪ 9007199254740991n
它也可以使用 toString() 方法,把它转成字符串格式;
const hugeString = BigInt("0x1fffffffffffff");
console.log(hugeString.toString()) // "9007199254740991"
它在某些方面类似于 Number ,但是也有几个关键的不同点:不能用于 Math 对象中的方法;不能和任何 Number 实例混合运算,两者必须转换成同一种类型。在两种类型来回转换时要小心,因为 BigInt
变量在转换成 Number 变量时可能会丢失精度。
类型判断
是用 typeof 判断类型时,BigInt
对象返回 "bigint" :
typeof 1n === 'bigint'; // true
typeof BigInt('1') === 'bigint'; // true
使用 Object
包装后, BigInt
被认为是一个普通 "object" :
typeof Object(1n) === 'object'; // true
运算
BigInt 类型的数据不能和 Number、Undefined、Null 类型的数据进行计算。
1n + 1;
// Uncaught TypeError: Cannot mix BigInt and other types, use explicit conversions at <anonymous>
以下操作符可以和 BigInt
一起使用: +
、*
、\
、-
、**
、%
。除 >>>
(无符号右移)之外的位操作也可以支持。因为 BigInt
都是有符号的, >>>
(无符号右移)不能用于 BigInt
。BigInt
不支持单目 (+
) 运算符。
const previousMaxSafe = BigInt(Number.MAX_SAFE_INTEGER);
// ↪ 9007199254740991n
const maxPlusOne = previousMaxSafe + 1n;
// ↪ 9007199254740992n
const theFuture = previousMaxSafe + 2n;
// ↪ 9007199254740993n
const multi = previousMaxSafe * 2n;
// ↪ 18014398509481982n
const subtr = multi – 10n;
// ↪ 18014398509481972n
const mod = multi % 10n;
// ↪ 2n
const bigN = 2n ** 54n;
// ↪ 18014398509481984n
bigN * -1n
// ↪ –18014398509481984n
BigInt 没有小数部分,他是一个整数,所以如果使用除法 /
,结果会向零取整。
const expected = 4n / 2n;
// 2n
const rounded = 5n / 2n;
// 2n
Number 和 BigInt
BigInt
和 Number
在严格情况下是不等的。
0n === // false
0n == 0 // true
Number
和 BigInt
可以进行比较。
1n < 2
// ↪ true
2n > 1
// ↪ true
两者也可以混在一个数组内并排序。
const mixed = [4n, 6, -12n, 10, 4, 0, 0n];
// ↪ [4n, 6, -12n, 10, 4, 0, 0n]
mixed.sort();
// ↪ [-12n, 0, 0n, 10, 4n, 4, 6]
BigInt
在需要转换成 Boolean
的时表现跟 Number
类似:如通过 Boolean 函数转换;用于 ||
, &&
, 和 !
的操作数;或者用于在像 if else
这样的条件语句中。
if (0n) {
console.log('yes');
} else {
console.log('no');
}
// "no"
0n || 12n
// 12n
0n && 12n
// 0n
Boolean(0n)
// false
Boolean(12n)
// true
!12n
// false
!0n
// true
方法
BigInt.asIntN(width, bigint)
将 BigInt 值转换为一个 -2^(width-1)
与 2^(width-1)-1
之间的有符号整数。
// 因为 -2^(4-1) = -8n 和 2^(4-1) - 1 = 7n
console.log(BigInt.asIntN(4, 7n)); // 7n 存在这个范围内,所以直接返回
console.log(BigInt.asIntN(4, 8n)); // -8n
BigInt.asUintN(width, bigint)
BigInt.asUintN
静态方法将 BigInt
转换为一个 0 和 2^(width-1) 之间的无符号整数。
总结
BigInt
用于当整数值大于Number
数据类型支持的范围时。这种数据类型允许我们安全地对大整数执行算术操作,表示高分辨率的时间戳,使用大整数id等等。