如何将数字格式化为 1K、1M、1B

使用紧凑表示法以节省空间且易读的方式显示大数字

简介

大数字不仅占用较多空间,也难以快速浏览。例如,1,500,000 需要七位数字和格式化,而 1.5M 只需三个字符即可表达相同的数量级。这种紧凑表示法在社交媒体粉丝数、视频播放量、仪表盘指标和文件大小等场景中非常常见。

JavaScript 通过内置的 Intl.NumberFormat API 提供了紧凑数字格式化的支持。该 API 能自动完成数字转换,并根据不同语言和地区调整格式,确保所有用户都能正确显示数字。

为什么大数字需要紧凑格式

在用户界面中显示大数字时,会遇到两个问题。首先,数字会占用较多的横向空间。例如,1,234,567 次浏览比 1.2M 次浏览需要更多空间。其次,用户处理紧凑数字的速度更快。人脑识别 1.5M 代表一百五十万的速度远快于解析 1,500,000。

紧凑表示法通过用数量级字母替换末尾的零,解决了这两个问题。它只显示有效数字,并在后面加上代表数量级的字母。这种方式在保证可读性的同时兼顾了精度。

不同场景对精度的要求不同。例如,社交媒体粉丝数通常不需要精确到个位,显示 1.2M 粉丝而不是 1,234,567 已足够。而金融仪表盘可能需要更高的精度,比如显示 1.23M 而不是 1.2M。Intl API 允许你在保持紧凑格式的同时灵活控制精度。

在 JavaScript 中使用紧凑表示法

notation 选项在 Intl.NumberFormat 中用于控制数字的显示方式。将其设置为 "compact" 可启用紧凑格式。

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

console.log(formatter.format(1500));
// Output: "1.5K"

console.log(formatter.format(1500000));
// Output: "1.5M"

console.log(formatter.format(1500000000));
// Output: "1.5B"

格式化器会根据数字的大小自动选择合适的数量级标识。千用 K,百万用 M,十亿用 B。格式化器还会将数字缩减为易读的形式,例如显示 1.5K 而不是 1,500。

你无需编写逻辑来判断何时使用 K、M 或 B。Intl API 会根据数字的数量级自动处理。

紧凑表示法如何格式化不同数量级

紧凑表示法会在不同的数量级应用不同的格式。了解这些阈值有助于你预测数字的显示方式。

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

console.log(formatter.format(500));
// Output: "500"

console.log(formatter.format(1000));
// Output: "1K"

console.log(formatter.format(1500));
// Output: "1.5K"

console.log(formatter.format(999000));
// Output: "999K"

console.log(formatter.format(1000000));
// Output: "1M"

console.log(formatter.format(1500000));
// Output: "1.5M"

console.log(formatter.format(1000000000));
// Output: "1B"

console.log(formatter.format(1000000000000));
// Output: "1T"

小于一千的数字不会进行紧凑处理。一旦数字达到一千,就会切换为 K 表示法。对于百万、十亿和万亿也采用类似的模式。

格式化器会对数字进行四舍五入以适应紧凑表示。例如,1,234,567 默认会显示为 1.2M。下一课将介绍如何控制紧凑表示中小数位数的显示。

选择短格式和长格式显示

紧凑表示法提供两种显示风格。短格式使用 K、M、B 等字母,长格式则将数量级完整拼写出来。

const shortFormatter = new Intl.NumberFormat("en-US", {
  notation: "compact",
  compactDisplay: "short"
});

console.log(shortFormatter.format(1500));
// Output: "1.5K"

console.log(shortFormatter.format(1500000));
// Output: "1.5M"

const longFormatter = new Intl.NumberFormat("en-US", {
  notation: "compact",
  compactDisplay: "long"
});

console.log(longFormatter.format(1500));
// Output: "1.5 thousand"

console.log(longFormatter.format(1500000));
// Output: "1.5 million"

compactDisplay 选项用于控制此行为。它接受两个值:"short""long"。如果省略该选项,则默认为 "short"

短格式适用于空间有限的场景,如仪表盘卡片、移动端界面和数据表格,K、M、B 的简洁表达更为高效。长格式则适用于对清晰度要求更高的场景,如教育内容、财务报告和无障碍界面,完整拼写数量级更易于理解。

不同语言中的紧凑表示法工作原理

紧凑表示法会根据 locale 指定的语言和地区进行适配。不同语言在数量级指示符上使用不同的字母、词语和格式规范。

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

console.log(enFormatter.format(1500000));
// Output: "1.5M"

const frFormatter = new Intl.NumberFormat("fr-FR", {
  notation: "compact"
});

console.log(frFormatter.format(1500000));
// Output: "1,5 M"

const deFormatter = new Intl.NumberFormat("de-DE", {
  notation: "compact"
});

console.log(deFormatter.format(1500000));
// Output: "1,5 Mio."

const jaFormatter = new Intl.NumberFormat("ja-JP", {
  notation: "compact"
});

console.log(jaFormatter.format(15000000));
// Output: "1500万"

法语在 M 前加空格。德语用 Mio. 作为 Million(百万)的缩写。日语则采用完全不同的数字系统,用 万 表示一万。

这些差异会根据 locale 自动处理,无需编写特定于 locale 的代码来处理不同的数量级指示符。只需将用户的语言偏好传递给格式化器,即可生成该语言的正确输出。

长格式显示同样会根据每种语言进行适配。

const enFormatter = new Intl.NumberFormat("en-US", {
  notation: "compact",
  compactDisplay: "long"
});

console.log(enFormatter.format(1500000));
// Output: "1.5 million"

const frFormatter = new Intl.NumberFormat("fr-FR", {
  notation: "compact",
  compactDisplay: "long"
});

console.log(frFormatter.format(1500000));
// Output: "1,5 million"

const deFormatter = new Intl.NumberFormat("de-DE", {
  notation: "compact",
  compactDisplay: "long"
});

console.log(deFormatter.format(1500000));
// Output: "1,5 Millionen"

德语中,Million 的复数形式为 Millionen。法语中,million 没有加 s。Intl API 会自动处理这些语言差异。

小数字何时不会被紧凑化

低于紧凑阈值的数字会正常显示。该阈值因 locale 而异,但在大多数西方语言中通常从一千开始。

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

console.log(formatter.format(10));
// Output: "10"

console.log(formatter.format(100));
// Output: "100"

console.log(formatter.format(999));
// Output: "999"

console.log(formatter.format(1000));
// Output: "1K"

这种行为可以避免小数字出现不自然的格式。例如,显示 500 为 500 比显示为 0.5K 更清晰。格式化器只在有助于提升可读性时才应用紧凑表示法。

阈值并不总是一千。有些语言(如日语)采用不同的数字分组系统。日语以一万为分组单位,因此紧凑表示法的起始阈值可能不同。

const jaFormatter = new Intl.NumberFormat("ja-JP", {
  notation: "compact"
});

console.log(jaFormatter.format(9999));
// Output: "9999"

console.log(jaFormatter.format(10000));
// Output: "1万"

Intl API 会自动处理这些 locale 特定的阈值。

紧凑表示法与其他格式化选项的结合

紧凑表示法可与其他数字格式化选项配合使用。你可以在使用紧凑表示法的同时,控制小数位数、分组分隔符和四舍五入等。

const formatter = new Intl.NumberFormat("en-US", {
  notation: "compact",
  maximumFractionDigits: 1
});

console.log(formatter.format(1234567));
// Output: "1.2M"

const preciseFormatter = new Intl.NumberFormat("en-US", {
  notation: "compact",
  maximumFractionDigits: 2
});

console.log(preciseFormatter.format(1234567));
// Output: "1.23M"

const noDecimalsFormatter = new Intl.NumberFormat("en-US", {
  notation: "compact",
  maximumFractionDigits: 0
});

console.log(noDecimalsFormatter.format(1234567));
// Output: "1M"

选项 maximumFractionDigits 用于控制小数点后显示的位数。将其设置为 0 可以去除所有小数位,使数字显示更加简洁。

你还可以将紧凑表示法与最小位数选项结合使用,以确保不同数字范围内的格式保持一致。

const formatter = new Intl.NumberFormat("en-US", {
  notation: "compact",
  minimumFractionDigits: 1,
  maximumFractionDigits: 1
});

console.log(formatter.format(1000));
// Output: "1.0K"

console.log(formatter.format(1500));
// Output: "1.5K"

console.log(formatter.format(2000));
// Output: "2.0K"

这种方法可以确保所有数字都显示一位小数,有助于在表格和图表中保持视觉一致性。

何时使用紧凑表示法

当空间有限或对精确度要求不高时,紧凑表示法效果最佳。社交媒体计数、仪表盘指标和汇总统计都是理想的应用场景。用户无需知道某个视频的观看次数是 1,234,567,只需了解有 1.2M 次观看即可。

当需要精确数字时,不要使用紧凑表示法。金融交易、科学测量和法律文件都需要完整的精度。例如,银行余额应显示 $1,234.56,而不是 $1.2K;发票应显示 $1,500.00,而不是 $1.5K。

请根据受众和场景进行选择。数据分析师可能更喜欢看到完整数字以便了解精确数值,而普通用户通常更喜欢紧凑数字,因为这样更易于快速理解。有些界面会同时提供两种选项,默认显示紧凑数字,并允许用户按需查看精确数值。

紧凑表示法同样适用于文件大小,但实现方式略有不同。文件大小通常采用 1024 的幂而不是 1000,因此会用到 kibibyte 和 mebibyte,而不是 kilobyte 和 megabyte。Intl API 不支持二进制单位,因此文件大小格式化需要自定义逻辑或专用库。