ES10虽然还是一个草案,但是其中添加的一些特性给前端带来了巨大的变化,让js语言更加精进。今天我们就来聊一聊ES10的新特性之一 BigInt (任意精度整数)。
ES6之后JavaScript的基本数据类型增加到6种:
- String
- Number
- Boolean
- Undefiend
- Null
- Symbol。
目前BigInt还处于stage-4阶段,不出意外即将成为js的第七种基本数据类型和第二个数字数据类型。
问题
我们都知道在js中Number类型是按照按照IEEE754-2008标准的定义,所有数字都以双精度64位浮点格式表示,在此标准范围内,js的Number类型只能安全地表示-9007199254740991 (-(2^53-1)) 和9007199254740991(2^53-1)之间的整数,任何超出此范围的整数值都可能被自动四舍五入丢失精度。
意外的四舍五入精度丢失,有可能会对程序安全性造成损害,甚至对用户和公司造成财产损失。
在这里讨论这个问题也是因为确确实实踩到了这个坑,大概说一下问题,昨天晚上有用户反馈白名单设置有bug,造成部分白名单限制失效,然后就跟后端一起排查,最终定位到问题是:后端返回的白名单用户ID是数字类型,位数达到18位,早已超出了最大安全数9007199254740991,发生了精度丢失。
解决方案
相信大多数人应该都能想到,使用字符串类型表示大数,机智如我,最终我也是通过这种方式进行的紧急修复上线。业界也有成熟的方案库,以便更容易地处理大整数,例如,例如 bignumber.js。
现在有了BigInt,所有比Number.MAX_SAFE_INTEGER大的数都可以不用再通过变通的方法和担心有精度丢失的风险。
语法
可以用在一个整数字面量后面加 n 的方式定义一个 BigInt ,如:10n,或者调用函数BigInt(value);value可以是数字或字符串
注意:Bigint不是构造函数,不能使用new 操作符。
类型信息
使用 typeof 测试时, BigInt 对象返回 "bigint"
typeof 123n === 'bigint'; // true
typeof BigInt('123') === 'bigint'; // true
123n == 123 // true
使用 Object 包装后, BigInt 被认为是一个普通 "object" :
typeof Object(123n) === 'object'; // true
运算
以下操作符可以和 BigInt 一起使用: +、*、-、**、% 。除 >>> (无符号右移)之外的 位操作 也可以支持。因为 BigInt 都是有符号的, >>> (无符号右移)不能用于 BigInt。为了兼容 asm.js ,BigInt 不支持单目 (+) 运算符。
const previousMaxSafe = BigInt(Number.MAX_SAFE_INTEGER);
const maxPlusOne = previousMaxSafe + 1n; // 9007199254740992n
const multi = previousMaxSafe * 2n; //18014398509481982n
const mod = multi % 10n; // 2n
当使用 BigInt 时,带小数的运算会被取整
const expected = 4n / 2n; // 2
const rounded = 5n / 2n // 2
方法介绍
静态方法
BigInt.asIntN() : 将 BigInt 值转换为一个 -2width - 1 与 2width-1-1 之间的有符号整数。
BigInt.asUintN() : 将一个 BigInt 值转换为 0 与 2width-1 之间的无符号整数。
实例方法
BigInt.prototype.toLocaleString()
返回此数字的 language-sensitive 形式的字符串。覆盖 Object.prototype.toLocaleString() 方法。
BigInt.prototype.toString()
返回以指定基数(base)表示指定数字的字符串。覆盖 Object.prototype.toString() 方法。
BigInt.prototype.valueOf()
返回指定对象的基元值。 覆盖 Object.prototype.valueOf() 方法。
结尾
由于在 Number 与 BigInt 之间进行转换会损失精度,因而建议仅在值可能大于253 时使用 BigInt 类型,并且不在两种类型之间进行相互转换。
对任何 BigInt 值使用 JSON.stringify() 都会引发 TypeError,因为默认情况下 BigInt 值不会在 JSON 中序列化。
以上就是对于javaScript新基本类型Bigint的基本介绍,喜欢文章的小伙伴可以点赞,欢迎留言交流讨论!也欢迎大佬对文章中的错误进行斧正