Intl.NumberFormat:数字、货币、百分比、单位
(1234567.89).toLocaleString() 就是在用它。同一个数,分组符是 , 还是 . 还是空格、小数点用 . 还是 ,、货币符在前还是在后、负号怎么放——全按 locale
走。它还支持紧凑写法(1.2M)、百分比、带单位(20 km/h)、有效数字与舍入。
1 · 同一个数在各 locale 下的写法
把 1234567.89 传给不同 locale 的 NumberFormat,只看分组与小数的差异:
2 · 全功能 playground
调 locale 与 options,实时看成品、resolvedOptions() 与对应代码:
3 · formatToParts:把成品拆成零件
format() 给出一整串,而 formatToParts() 给出一个数组,每块标了 type(integer / group / decimal / fraction / currency / unit / literal …)。要给「整数大、小数小」做样式、或单独提取货币符时就用它。下面是当前 playground 配置的拆解:
4 · formatRange:区间的拼接
formatRange(a, b) 用 locale 正确的连接号拼区间:en-US 下 formatRange(3, 5) 得 3–5,货币 style 下得 $3.00 – $5.00——两侧各带一次符号,而 de-DE 的
3,00–5,00 € 只出现一次,是因为欧元符是后缀、落在共享段。真正的「合并」体现在 formatRangeToParts 的 source 字段(共享段标 shared)与两值相等时前置的近似号 ~(实测 formatRange(3, 3) 得 ~$3.00):
几个高频配置: 货币 → { style:'currency', currency:'JPY' }(日元自动 0 位小数);百分比 → { style:'percent' } 传 0.25 得 25%(它自动 ×100);大数 → { notation:'compact' };控制精度 → maximumFractionDigits 或
maximumSignificantDigits + roundingMode。
金额不要用 Number 存。NumberFormat 只负责显示;金额计算请用整数分或十进制库,不要用浮点数计算金额再格式化。格式化 ≠ 精确运算。