•
阅读 3 分钟
ES 提案:数字分隔符
由 Sam Goto 和 Rick Waldron 提出的 ES 提案 “Numeric Separators” 正处在 stage 3。这篇博客文章讲解它是如何工作的。
什么是数字?
JavaScript 有几种数字:
- 十进制数字:123.45,86,12e-5
- 二进制整数数字:0b1011
- 八进制整数数字:0o765
- 十六进制整数数字:0x2FF
有意思的是,一元减(-
)是一个运算符而不是数字文字的一部分(除了十进制数字中的有符号指数)。
分组数字
分组数字使其具有更好的可读性是有悠久的历史的。举例来说:
- 截至 2016 年底,慕尼黑拥有 1,464,301 名居民。
- 地球与太阳之间的距离为 149,600,000 公里。
新的提案允许在数字中使用下划线作为分隔符:
const inhabitantsOfMunich = 1_464_301
const distanceEarthSunInKm = 149_600_000
对于其它的进制数,分组显得同样重要:
const fileSystemPermission = 0b111_111_000
const bytes = 0b1111_10101011_11110000_00001101
const words = 0xFAB_F00D
也可以在分数和指数中使用分隔符:
const massOfElectronInKg = 9.109_383_56e-31
const trillionInShortScale = 1e1_2
约束
需要记住的关键的约束是:你只能在两个数字之间使用下划线分隔符。因此,下面的数字是非法的。
3_.141
3._141
1_e12
1e_12
_1464301 /* valid variable name! */
1464301_
0_b111111000
0b_111111000
另外,绝不能连续使用超过一个下划线在同一行中:
123__456; /* two underscores – not allowed */
这些约束的动机是使事情保持简单。
BigInt(任意精度整数)和数字分隔符
BigInt 能够用数字表示大型数。因此,数字分隔符对它们特别有用:
const massOfEarthInKg = 6_000_000_000_000_000_000_000_000n
BigInt 通常用于代表金融技术领域的资金。分隔符也可以在这里提供帮助:
const priceInCents = 123_000_00 // 123千美元
转换带有分隔符的数字
下面的转换函数不支持分隔符:
- Number()
- parseInt()
- parseFloat()
举例来说:
Number('123_456') // NaN
Number.parseInt('123_456') // 123
原因是数字分隔符是针对代码的。其它类型的输入应该以不同的方式处理
一个转换分隔符数字的辅助函数
一种转换分隔符数字的方法是删除非数字字符:
const RE_NON_DIGIT = /\D/gu
function removeNonDigits(str) {
str = str.replace(RE_NON_DIGIT, '')
return Number(str)
}
使用这个函数:
removeNonDigits('149,600,000') // 149600000
removeNonDigits('1_407_836') // 1407836
提示 Tips
不要忘记指数表示法
使用尾随零,指数表示法可能比分组零更方便。对比:
const timeoutInMilliseconds = 10e3 /* 10 秒 */
const tenSecondTimeout = 10_000 /* 10 秒 */
数字并不总是表示数字数据的最佳选择
一些数据,如电话号码,信用卡号码和社会安全号码,在一些方面是数字,而在其他方面则不是:可能有非数字前缀和分隔符,前导数字很重要。它们也不应该以指数表示法表示。
因此避免如此:
// 不要这样做:
const phoneNumber = 555_2368
const creditCardNumber = 378_2822_4631_0005
const socialSecurityNumber = 111_11_1111
本文由 吳文俊 翻译,原文地址 ES2021: numeric separators