功能说明
formatCompactNumber 把数值转换为紧凑记法,例如 1200 在不同语言下显示为 1.2K 或 1.2万,适合仪表盘指标、社交计数、下载量和表格摘要。函数接受 locale 与 Intl.NumberFormat 选项,默认保留一位小数并使用短形式。formatCompactRange 把一组值格式化为用短横线连接的区间文本,便于展示统计范围。
关键代码
函数先拒绝非数字、NaN 和 Infinity,避免 Intl 返回 “NaN” 这类不可控文本。随后从选项中取出 maximumFractionDigits 并单独校验,其余选项原样传给 Intl.NumberFormat,因此调用方仍可设置 signDisplay、useGrouping 等能力。每次调用都会创建格式化器,代码保持无隐藏缓存,行为可预测。区间函数只负责映射与拼接,不改变数值。
使用注意
紧凑记法会牺牲精度,1.24K 与 1.26K 可能显示成同一个字符串,不应把格式化结果反解析为数值。不同语言的单位不同,中文可能输出万或亿,日志与测试不要硬编码英文后缀。负数和零由 Intl 处理,若业务要求始终显示正负号可传入 signDisplay。该 API 依赖 Intl 数据,极旧环境可能缺少 compact 支持,需要降级方案。
验证方式
用 999、1000、1500、1000000 等边界检查输出,并断言小数位设置生效。切换 en 与 zh-CN 验证单位差异,测试负数和零。覆盖 NaN、Infinity、字符串输入与非法 maximumFractionDigits,确认抛出错误。区间函数测试空数组、单元素和多元素拼接,并确认自定义选项如 signDisplay 能正确透传。
代码示例
export function formatCompactNumber(value, locale = "en", options = {}) {
if (typeof value !== "number" || !Number.isFinite(value)) {
throw new TypeError("value must be a finite number");
}
const { maximumFractionDigits = 1, ...rest } = options;
if (!Number.isInteger(maximumFractionDigits) || maximumFractionDigits < 0) {
throw new RangeError("maximumFractionDigits must be a non-negative integer");
}
return new Intl.NumberFormat(locale, {
notation: "compact",
compactDisplay: "short",
maximumFractionDigits,
...rest,
}).format(value);
}
export function formatCompactRange(values, locale = "en") {
if (!Array.isArray(values)) throw new TypeError("values must be an array");
return values.map((value) => formatCompactNumber(value, locale)).join(" – ");
}