如何控制是否显示千位分隔符?

使用 useGrouping 选项可在格式化数字时启用或禁用分组分隔符

简介

当你格式化数字 123456 时,可能会看到 "123,456" 这种带有逗号作为千位分隔符的格式,或者 "123456" 这种没有任何分隔符的格式。用于分隔数字组的字符称为分组分隔符,在英语地区通常被称为千位分隔符。

不同场景对数字格式有不同要求。财务报表通常会显示分组分隔符,以便于阅读大数字。而技术展示如序列号、产品编码和 ID 号则通常省略分隔符,以避免混淆。useGrouping 选项在 Intl.NumberFormat 中用于控制格式化输出中是否显示这些分隔符。

本指南将介绍如何启用和禁用分组分隔符、不同语言环境下的分隔符差异,以及在应用中应如何选择设置。

通过 useGrouping false 禁用分组分隔符

useGrouping 设置为 false,即可移除格式化数字中的所有分组分隔符。

const formatter = new Intl.NumberFormat('en-US', {
  useGrouping: false
});

formatter.format(123456);
// "123456"

formatter.format(1234567.89);
// "1234567.89"

无论数字多大,格式化结果都不会包含逗号或其他分组字符。小数点分隔符仍然保留,因为 useGrouping 只影响数字分组,不影响小数格式。

此设置适用于所有数字样式,包括货币和单位。

new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD',
  useGrouping: false
}).format(1234567.89);
// "$1234567.89"

new Intl.NumberFormat('en-US', {
  style: 'unit',
  unit: 'kilometer',
  useGrouping: false
}).format(50000);
// "50000 km"

货币符号和单位标签会正常显示,但数字内部没有分隔符。

通过 useGrouping true 启用分组分隔符

useGrouping 设置为 true,即可包含分组分隔符。这是默认行为,只有在需要明确表达意图或覆盖配置时才需显式指定。

const formatter = new Intl.NumberFormat('en-US', {
  useGrouping: true
});

formatter.format(123456);
// "123,456"

formatter.format(1234567.89);
// "1,234,567.89"

格式化器按照英文习惯每三位插入一个逗号,这样可以让大数字更易于快速识别。

由于 true 是默认值,这两个格式化器的效果是一样的。

new Intl.NumberFormat('en-US', { useGrouping: true });
new Intl.NumberFormat('en-US');

这两种格式化器的输出都包含分组分隔符。

了解不同语言环境下的分组差异

不同的语言环境会使用不同的分组符号,并遵循不同的分组模式。useGrouping 选项用于控制是否进行分组,而具体使用什么分隔符以及分隔位置则由 locale 决定。

new Intl.NumberFormat('en-US', {
  useGrouping: true
}).format(1234567);
// "1,234,567"

new Intl.NumberFormat('de-DE', {
  useGrouping: true
}).format(1234567);
// "1.234.567"

new Intl.NumberFormat('fr-FR', {
  useGrouping: true
}).format(1234567);
// "1 234 567"

英文使用逗号,德文用句点,法文用空格。这三种都是分组分隔符,但由于各自的语言环境不同,表现形式也不同。

有些语言环境采用不同的分组模式。例如,印度数字分组方式是先分三位,之后每两位分组。

new Intl.NumberFormat('en-IN', {
  useGrouping: true
}).format(1234567);
// "12,34,567"

分组分隔符会在最右侧的三位数字后出现,然后每隔两位插入一次,最终生成 12,34,567,而不是 1,234,567

当你通过 useGrouping: false 禁用分组时,这些与语言环境相关的差异就会消失,因为不会再有任何分隔符出现。

new Intl.NumberFormat('en-IN', {
  useGrouping: false
}).format(1234567);
// "1234567"

使用字符串值实现高级分组控制

useGrouping 选项支持字符串值,可以更精细地控制分组分隔符的显示时机。这些值属于 Intl.NumberFormat V3 规范的一部分,并已在现代浏览器中得到支持。

"always" 的效果等同于 true,始终显示分组分隔符。

new Intl.NumberFormat('en-US', {
  useGrouping: 'always'
}).format(1234);
// "1,234"

"auto" 的值会遵循当前 locale 的分组偏好。大多数语言环境倾向于显示分组分隔符,因此 "auto" 实际上与 "always" 类似。当 notation 不是 "compact" 时,这是默认值。

new Intl.NumberFormat('en-US', {
  useGrouping: 'auto'
}).format(1234);
// "1,234"

"min2" 值仅在首组中至少有两位数字时才显示分组分隔符。对于四位数,这意味着不会显示分隔符。

new Intl.NumberFormat('en-US', {
  useGrouping: 'min2'
}).format(1234);
// "1234"

new Intl.NumberFormat('en-US', {
  useGrouping: 'min2'
}).format(12345);
// "12,345"

数字 1234 的首组只有一位数字(即 1),因此不会显示分隔符。而数字 12345 的首组有两位数字(即 12),因此会显示分隔符。

这种行为与某些语言环境下的数字格式化方式一致。例如,西班牙语通常在四位数字时省略分组分隔符。

new Intl.NumberFormat('es-ES', {
  useGrouping: 'auto'
}).format(1234);
// "1234"

new Intl.NumberFormat('es-ES', {
  useGrouping: 'auto'
}).format(12345);
// "12.345"

"auto" 值会遵循这些本地化偏好,而 "always" 则会覆盖这些设置。

new Intl.NumberFormat('es-ES', {
  useGrouping: 'always'
}).format(1234);
// "1.234"

选择何时禁用分组分隔符

当数字表示代码、标识符或技术值而非数量时,应禁用分组分隔符。

序列号和产品编码不应包含分组分隔符。

const serialNumber = 1234567890;

new Intl.NumberFormat('en-US', {
  useGrouping: false
}).format(serialNumber);
// "1234567890"

这样可以避免用户误认为分隔符是实际值的一部分。例如,看到 1,234,567,890 时,用户可能会疑惑逗号是否有意义,或者在其他地方输入该数字时是否需要输入逗号。

邮政编码、电话号码(以纯数字格式显示时)以及其他固定格式的标识符,建议禁用分组分隔符。

const zipCode = 90210;

new Intl.NumberFormat('en-US', {
  useGrouping: false,
  minimumIntegerDigits: 5
}).format(zipCode);
// "90210"

用于调试或日志记录的技术显示通常应禁用分组分隔符,以便准确显示数值本身。

console.log(`Processing ${
  new Intl.NumberFormat('en-US', {
    useGrouping: false
  }).format(bytesProcessed)
} bytes`);
// "Processing 1234567 bytes"

数字输入表单在编辑时通常会禁用分组分隔符,以避免用户混淆是否需要输入分隔符。用户输入完成后,格式化显示可以再添加分组。

选择何时启用分组分隔符

对于表示数量、测量值或金额等需要用户快速读取和理解的数字,建议启用分组分隔符。

财务金额使用分组分隔符后更易于浏览。

new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD',
  useGrouping: true
}).format(1234567.89);
// "$1,234,567.89"

分隔符有助于用户一眼区分 $1,234,567$123,456

统计数据、分析仪表盘和显示计数的报告都能从分组中受益。

const pageViews = 5432198;

new Intl.NumberFormat('en-US', {
  useGrouping: true
}).format(pageViews);
// "5,432,198 views"

较大的测量值通过分组后更易于阅读。

new Intl.NumberFormat('en-US', {
  style: 'unit',
  unit: 'kilometer',
  useGrouping: true
}).format(384400);
// "384,400 km"

例如,这个距离(约为地球到月球的距离)以 384,400 的形式比 384400 更易于阅读。

在任何需要用户理解数字量级的场景下,分组分隔符都能带来帮助。分隔符为数字创建了视觉锚点,有助于大脑分块处理数字。

使用 min2 优化四位数显示效果

"min2" 值可为四位或五位数字提供更简洁的显示效果。例如,年份通常不加分隔符会更美观。

new Intl.NumberFormat('en-US', {
  useGrouping: 'min2'
}).format(2025);
// "2025"

new Intl.NumberFormat('en-US', {
  useGrouping: 'always'
}).format(2025);
// "2,025"

大多数读者在表示年份时,觉得 20252,025 更自然。"min2" 设置可自动实现此效果。

某些价格区间也适合采用这种方式。

const price = 1299;

new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD',
  useGrouping: 'min2'
}).format(price);
// "$1299.00"

部分零售商倾向于将 $1299 这样的价格不加逗号显示,以在心理上让价格看起来更低。当价格超过四位数时,分隔符会自动出现。

new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD',
  useGrouping: 'min2'
}).format(12999);
// "$12,999.00"

这样可以在整个价格区间内实现一致的显示效果,无需手动判断数字的位数。

了解紧凑表示法如何影响分组

当使用紧凑表示法时,默认的 useGrouping 行为会变为 "min2",而不是 "auto"。这样可以避免在紧凑格式中出现不必要的分隔符。

new Intl.NumberFormat('en-US', {
  notation: 'compact'
}).format(1234);
// "1.2K"

new Intl.NumberFormat('en-US', {
  notation: 'compact',
  useGrouping: 'always'
}).format(1234);
// "1.2K"

紧凑表示法已经对数字进行了缩写,因此内部分组分隔符会显得多余。格式化器会自动处理这一点,但如有需要你也可以手动覆盖。

检查当前激活的分组设置

resolvedOptions() 方法可以显示格式化器实际使用的 useGrouping 值。

const formatter = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD'
});

formatter.resolvedOptions().useGrouping;
// "auto"

即使创建格式化器时没有显式设置 useGrouping,解析选项时仍会显示默认值 "auto"

const compactFormatter = new Intl.NumberFormat('en-US', {
  notation: 'compact'
});

compactFormatter.resolvedOptions().useGrouping;
// "min2"

如解析选项所示,紧凑表示法格式化器默认采用 "min2",而不是 "auto"

此方法有助于通过显示格式化器实际使用的设置来调试意外的分组行为。