Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

你可能还不清楚的JavaScript类型——BigInt #89

Open
GpingFeng opened this issue Aug 14, 2022 · 0 comments
Open

你可能还不清楚的JavaScript类型——BigInt #89

GpingFeng opened this issue Aug 14, 2022 · 0 comments

Comments

@GpingFeng
Copy link
Owner

我们知道,现在 JavaScript 有 7 种基础类型,null/undefined/number/string/boolean/bigint/symbol。其中 bigint 是 ES2020 中正式加入的,有个别的面试官喜欢深挖这个特性,那么我们来了解一下 BigInt 到底是什么?我们为什么需要 BigInt 吧?

BigInt 是什么?

概念

我们知道 JavaScript 中 Number 类型最大的数值为 2^53- 1,也就是 Number.MAX_SAFE_INTEGER。

BigInt 是一种内置对象,它提供了一种方法来表示大于 2^53 - 1 的整数。
也就是说,BigInt 可以表示任意大的整数。

声明

可以在一个整数字面量后面加上 n 或者调用函数 BigInt() 定义一个 BigInt。如下:

const theBiggestInt = 9007199254740991n;
const alsoHuge = BigInt(9007199254740991);
// ↪ 9007199254740991n

类型检测

typeof 检测 BigInt 对象返回 bigint 字符串。

typeof 1n === 'bigint'; // true
typeof BigInt('1') === 'bigint'; // true

BigInt 基础语法和注意点

BigInt 很多时候表现跟 Number 类型很像,但也有很多不同的点,这些点在用到 BigInt 类型的时候,需要思考以下的点:

运算:

语法点 支持度 备注
+、*、-、**、% 支持
/ 不支持 会进行向下取整
单目 (+) 运算符 不支持
>>>(无符号右移) 不支持 因为 BigInt 都是有符号的
位运算(除了无符号右移) 支持
Math 对象方法 不支持

说明:

  • 除法的时候,当使用 BigInt 时,带小数的运算会被取整
const expected = 4n / 2n;
// ↪ 2n

const rounded = 5n / 2n;
// ↪ 2n, not 2.5n
  • 与 Number 混合运算的话。必须转换成同一种类型,有时候会造成精度丢失的问题,所以不建议这么使用
  • 在对象中使用 BigInt 的时候,假如使用 JSON.stringify() 会发生类型错误(TypeError)

综上所述,可以看到 BigInt 的使用需要注意的点还是非常多的,并且在和 Number 类型转换的时候还会发生精度丢失问题,因而建议仅在值可能大于2^53 时使用 BigInt 类型。

那么 BigInt 现在有哪些应用场景呢?

BigInt 的应用场景

高精度时间戳

大于 2^53 - 1 的整数的一个应用场景就是高精度时间戳。精确到纳秒级别的时间戳很常见,经常用来记录特定程序的执行事件,以便进行性能分析,BigInt 可以表示高精度时间戳,在后端性能分析、性能调优中发挥作用。

大整数 ID

比如 Twitter 的 id 生成服务,当 id 持续增长时,就会超出 JS 的安全范围,因此要求同时冗余地返回字符串型的 id。假如有 BigInt 类型就可以直接使用。

兼容性 & PolyFill

can i use 中的数据显示,Chrome 的支持度会好很多,IE 全军覆没,整体覆盖 92.25% 的用户。

现在可以使用 JSBI — pure-JavaScript BigInts 这个库来实现 BigInt。JSBI 是直接使用了 V8 和 Chrome 中 BigInt 的设计和实现方式,功能与浏览器中一致,语法稍有不同。假如 BigInt 被所有的浏览器原生支持后,可以使用 babel 插件 babel-plugin-transform-jsbi-to-bigint 移除 JSBI 转为原生的 BigInt 语法。

总结

总体而言,BigInt 可以表示任意大的整数,目前的使用场景是相对较少的。BigInt 的使用需要注意的点还是非常多的,因而建议仅在值可能大于2^53 时使用 BigInt 类型。目前的兼容性一般,可以考虑使用 jsbi 这个库替代。

参考

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant