
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
parseInt('123_456'); // 123
原因是数字分隔符是针对代码的。其它类型的输入应该以不同的方式处理
一个转换分隔符数字的辅助函数
一种转换分隔符数字的方法是删除非数 字字符:
const RE_NON_DIGIT = /[^0-9]/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;
本文作者 Axel Rauschmayer,转载请注明来源链接: