Web 平台 API / Intl · 浏览器内置的本地化引擎 / Intl.NumberFormat:数字、货币、百分比、单位 待审核 5 / 9
NumberFormat · 数字/货币/单位

Intl.NumberFormat:数字、货币、百分比、单位

(1234567.89).toLocaleString() 就是在用它。同一个数,分组符是 , 还是 . 还是空格、小数点用 . 还是 ,、货币符在前还是在后、负号怎么放——全按 locale 走。它还支持紧凑写法(1.2M)、百分比带单位(20 km/h)、有效数字与舍入

1 · 同一个数在各 locale 下的写法

1234567.89 传给不同 locale 的 NumberFormat,只看分组与小数的差异:

图 1-1 · 同一个数在各 locale 下分组与小数写法的差异。

2 · 全功能 playground

调 locale 与 options,实时看成品、resolvedOptions() 与对应代码:

图 2-1 · NumberFormat 的实时试验台,可调 locale 与各 options,同时给出 resolvedOptions 与对应代码。

3 · formatToParts:把成品拆成零件

format() 给出一整串,而 formatToParts() 给出一个数组,每块标了 type(integer / group / decimal / fraction / currency / unit / literal …)。要给「整数大、小数小」做样式、或单独提取货币符时就用它。下面是当前 playground 配置的拆解:

图 3-1 · formatToParts 拆出的各段与其类型。

4 · formatRange:区间的拼接

formatRange(a, b) 用 locale 正确的连接号拼区间:en-USformatRange(3, 5)3–5,货币 style 下得 $3.00 – $5.00——两侧各带一次符号,而 de-DE3,00–5,00 € 只出现一次,是因为欧元符是后缀、落在共享段。真正的「合并」体现在 formatRangeToPartssource 字段(共享段标 shared)与两值相等时前置的近似号 ~(实测 formatRange(3, 3)~$3.00):

图 4-1 · formatRange 的输出与各段的 source 标记。

几个高频配置: 货币 → { style:'currency', currency:'JPY' }(日元自动 0 位小数);百分比 → { style:'percent' }0.25 得 25%(它自动 ×100);大数 → { notation:'compact' };控制精度 → maximumFractionDigitsmaximumSignificantDigits + roundingMode

金额不要用 Number 存。NumberFormat 只负责显示;金额计算请用整数分或十进制库,不要用浮点数计算金额再格式化。格式化 ≠ 精确运算。