面试官:聊聊 BigInt?
我们知道,现在 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'; // truetypeof 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[1] 中的数据显示,Chrome 的支持度会好很多,IE 全军覆没,整体覆盖 92.25% 的用户。
现在可以使用 JSBI — pure-JavaScript BigInts[2] 这个库来实现 BigInt。JSBI 是直接使用了 V8 和 Chrome 中 BigInt 的设计和实现方式,功能与浏览器中一致,语法稍有不同。假如 BigInt 被所有的浏览器原生支持后,可以使用 babel 插件 babel-plugin-transform-jsbi-to-bigint[3] 移除 JSBI 转为原生的 BigInt 语法。
总结
总体而言,BigInt 可以表示任意大的整数,目前的使用场景是相对较少的。BigInt 的使用需要注意的点还是非常多的,因而建议仅在值可能大于2^53 时使用 BigInt 类型。目前的兼容性一般,可以考虑使用 jsbi 这个库替代。
参考
JSBI — pure-JavaScript BigInts[4]
BigInt-MDN[5]
参考资料
[1]can i use: https://caniuse.com/?search=bigint
[2]JSBI — pure-JavaScript BigInts: https://github.com/GoogleChromeLabs/jsbi
[3]babel-plugin-transform-jsbi-to-bigint: https://github.com/GoogleChromeLabs/babel-plugin-transform-jsbi-to-bigint
[4]JSBI — pure-JavaScript BigInts: https://github.com/GoogleChromeLabs/jsbi
[5]BigInt-MDN: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/BigInt
相关文章
- 微软 Windows 11 Beta 22623.891(KB5020040)发布,带来任务管理器搜索功能
- 微软 Windows 11 修复一个 AMD 处理器 Spectre Variant 2 漏洞,多款处理器受影响
- 阿里 Seata 新版本终于解决了 TCC 模式的幂等、悬挂和空回滚问题
- 微软督促用户升级到 Windows 11 22H2,Windows 10 21H1 将停止支持
- 5G时代Web前端的边界拓展思考
- Windows 11 22621.819 发布,微软宣布因开发人员放假导致 12 月更新减少
- 微软发布首个原生支持 Arm64 的 Visual Studio 2022 正式版更新
- 微软发布免费 Windows 11 22H2 开发环境虚拟机,可用至明年1月10日
- 开发者立功,微软 Surface Duo 2 现已实现 Win11 初始支持
- Linux Lite 6.2 发布
- 基于 Windows 11 底层开发内核,微软 Windows Server VNext 预览版 25236 发布(附 ISO 镜像下载)
- 微软发布 Windows 11 Dev 预览版 Build 25236 更新,带来多项问题修复
- 微软 PowerToys 更新,可帮你找出 Windows 11 / Windows 10 上哪些进程正在占用该文件
- 使用Zadig从0到1搭建持续交付平台
- 微软 Windows 11 任务管理器终于要有搜索栏了
- 微软 Edge 浏览器增强 Windows 11/10、Mac 和安卓之间共享文件功能:“Drop”整合屏幕截图
- 英伟达承认驱动导致 Windows 11 任务管理器 GPU 使用率 100% 误报问题
- 通过示例来学习 Bash base64 的编码和解码
- 微软承认周二更新会导致 Windows 10 OneDrive 出错
- Windows 11 Dev 预览版 25231 新功能:可通过 Wi-Fi 面板直接打开并连接到手机热点