JS最新基本数据类型:BigInt

BigInt是JavaScript中用于处理大整数的新数据类型,解决了Number类型在大整数运算时的精度问题。BigInt可以安全地执行大整数运算,避免了四舍五入错误,并且提供了与Number不同的算术和比较操作。BigInt与Number不能直接混合运算,需要通过转换确保操作数类型一致。JSBI库为不支持BigInt的环境提供了纯JavaScript实现。
摘要由CSDN通过智能技术生成

BigInt数据类型的目的是比Number数据类型支持的范围更大的整数值。在对大整数执行数学运算时,以任意精度表示整数的能力尤为重要。使用BigInt,整数溢出将不再是问题。

此外,可以安全地使用更加准确时间戳,大整数ID等,而无需使用变通方法。 BigInt目前是第3阶段提案, 一旦添加到规范中,它就是JS 第二个数字数据类型,也将是 JS 第8种基本数据类型:

  • Boolean
  • Null
  • Undefined
  • Number
  • BigInt
  • String
  • Symbol
  • Object

引用数据类型统称为Object类型,细分的话有

  • Object
  • Array
  • Date
  • Function
  • RegExp

基本数据类型的数据直接存储在栈中;而引用数据类型的数据存储在堆中在栈中保存数据的引用地址,这个引用地址指向的是对应的数据,以便快速查找到堆内存中的对象。

顺便提一句,栈内存是自动分配内存的。而堆内存是动态分配内存的,不会自动释放。所以每次使用完对象的时候都要把它设置为null,从而减少无用内存的消耗
————————————————

在JS中,按照标准的定义,所有数字都以双精度64位浮点格式表示。在此标准下,无法精确表示的非常大的整数将自动四舍五入。确切地说,JS 中的Number类型只能安全地表示-9007199254740991 (-(2^53-1)) 和9007199254740991(2^53-1)之间的整数,任何超出此范围的整数值都可能失去精度。

console.log(9999999999999999);    // → 10000000000000000

该整数大于JS Number 类型所能表示的最大整数,因此,它被四舍五入的。意外四舍五入会损害程序的可靠性和安全性。这是另一个例子:

// 注意最后一位的数字
9007199254740992 === 9007199254740993;    // → true

JS 提供Number.MAX_SAFE_INTEGER常量来表示 最大安全整数,Number.MIN_SAFE_INTEGER常量表示最小安全整数:

const maxInt = Number.MAX_SAFE_INTEGER;
const minInt = Number.MIN_SAFE_INTEGER;
console.log(maxInt );		// 9007199254740991
console.log(minInt );		// -9007199254740991

使用BigInt,可以在标准JS中执行对大整数的算术运算,而不会有精度损失的风险。
要创建BigInt,只需在整数的末尾追加n即可。比较:

console.log(9007199254740995n);    // → 9007199254740995n
console.log(9007199254740995);     // → 9007199254740996

或者,可以调用BigInt()构造函数

BigInt("9007199254740995");    // → 9007199254740995n

请记住,不能使用严格相等运算符将BigInt与常规数字进行比较,因为它们的类型不同:

console.log(10n === 10);    // → false

console.log(typeof 10n);    // → bigint
console.log(typeof 10);     // → number

相反,可以使用等号运算符,它在处理操作数之前执行隐式类型转换

console.log(10n == 10);    // → true

除一元加号(+)运算符外,所有算术运算符都可用于BigInt

10n + 20n;    // → 30n
10n - 20n;    // → -10n
+10n;         // → TypeError: Cannot convert a BigInt value to a number
-10n;         // → -10n
10n * 20n;    // → 200n
20n / 10n;    // → 2n
23n % 10n;    // → 3n
10n ** 3n;    // → 1000n

const x = 10n;
++x;          // → 11n
--x;          // → 9n

不支持一元加号(+)运算符的原因是某些程序可能依赖于+始终生成Number的不变量,或者抛出异常。 更改+的行为也会破坏asm.js代码。

当然,与BigInt操作数一起使用时,算术运算符应该返回BigInt值。因此,除法(/)运算符的结果会自动向下舍入到最接近的整数。例如:

25 / 10;      // → 2.5
25n / 10n;    // → 2n

因为隐式类型转换可能丢失信息,所以不允许在bigint和 Number 之间进行混合操作。小数部分的Number不能精确地转换为BigInt。大于2^53的BigInt不能准确地转换为数字。由于这个限制,不可能对混合使用Number和BigInt操作数执行算术操作。

10 + 10n;    // → TypeError
Math.max(2n, 4n, 6n);    // → TypeError

请注意,关系运算符不遵循此规则,如下例所示:

10n > 5;    // → true

如果希望使用BigInt和Number执行算术计算,首先需要确定应该在哪个类型中执行该操作。为此,只需通过调用
Number()或BigInt()来转换操作数:

Number()BigInt()来转换操作数:
BigInt(10) + 10n;    // → 20n
// or
10 + Number(10n);    // → 20

当 Boolean 类型与BigInt 类型相遇时,BigInt的处理方式与Number类似,换句话说,只要不是0n,BigInt就被视为可识别的值:

if (5n) {
    // 这里代码块将被执行
}
if (0n) {
    // 这里代码块不会执行
}

排序BigInts和Numbers数组时,不会发生隐式类型转换:

const arr = [3n, 4, 2, 1n, 0, -1n];
arr.sort();    // → [-1n, 0, 1n, 2, 3n, 4]

位操作符如|、&、<<、>>和^对Bigint的操作方式与Number类似。下面是一些例子:

90 | 115;      // → 123
90n | 115n;    // → 123n
90n | 115;     // → TypeError

与其他基本类型一样,可以使用构造函数创建BigInt。传递给BigInt()的参数将自动转换为BigInt:

BigInt("10");    // → 10n
BigInt(10);      // → 10n
BigInt(true);    // → 1n
BigInt(10.2);     // → RangeError
BigInt(null);     // → TypeError
BigInt("abc");    // → SyntaxError
BigInt(10) * 10n;    // → 100n
BigInt(true) === 1n;    // → true

总结

BigInt是一种新的数据类型,用于当整数值大于Number数据类型支持的范围时。这种数据类型允许我们安全地对大整数执行算术操作,表示高分辨率的时间戳,使用大整数id,等等,而不需要使用库。

重要的是要记住,不能使用Number和BigInt操作数的混合执行算术运算,需要通过显式转换其中的一种类型。 此外,出于兼容性原因,不允许在BigInt上使用一元加号(+)运算符。

如图,兼容情况并不是很好。并且转换BigInt是一个极其复杂的过程,这会导致严重的运行时性能损失。目前,更好的选择是使用JSBI库,它是BigInt提案的纯JS实现。

这个库提供了一个与原生BigInt行为完全相同的API。下面是如何使用JSBI:

import JSBI from './jsbi.mjs';

const b1 = JSBI.BigInt(Number.MAX_SAFE_INTEGER);
const b2 = JSBI.BigInt('10');

const result = JSBI.add(b1, b2);

console.log(String(result));    // → '9007199254741001'
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值