Intl.NumberFormat() 构造函数

Intl.NumberFormat() 构造函数创建 Intl.NumberFormat 对象。

¥The Intl.NumberFormat() constructor creates Intl.NumberFormat objects.

Try it

语法

¥Syntax

js
new Intl.NumberFormat()
new Intl.NumberFormat(locales)
new Intl.NumberFormat(locales, options)

Intl.NumberFormat()
Intl.NumberFormat(locales)
Intl.NumberFormat(locales, options)

注意:可以使用或不使用 new 来调用 Intl.NumberFormat()。两者都会创建一个新的 Intl.NumberFormat 实例。但是,当在没有 new 的情况下调用它并且 this 值是另一个 Intl.NumberFormat 实例时,会出现特殊行为;见 返回值

¥Note: Intl.NumberFormat() can be called with or without new. Both create a new Intl.NumberFormat instance. However, there's a special behavior when it's called without new and the this value is another Intl.NumberFormat instance; see Return value.

参数

¥Parameters

locales Optional

带有 BCP 47 语言标记或 Intl.Locale 实例的字符串,或此类区域设置标识符的数组。当传递 undefined 或不支持任何指定的区域设置标识符时,将使用运行时的默认区域设置。有关 locales 论证的一般形式和解释,请参阅 Intl 主页参数说明

允许使用以下 Unicode 扩展键:

nu

参见 numberingSystem

该键也可以通过 options 设置(如下所列)。当两者都设置时,options 属性优先。

options Optional

一个东西。为了便于阅读,属性列表根据其用途分为几个部分,包括 语言环境选项款式选择数字选项其他选择

区域设置选项

¥Locale options

localeMatcher

要使用的区域设置匹配算法。可能的值为 "lookup""best fit";默认为 "best fit"。有关此选项的信息,请参阅 区域设置识别和协商

numberingSystem

用于数字格式化的编号系统,例如 "arab""hans""mathsans" 等。有关支持的编号系统类型的列表,请参阅 Intl.Locale.prototype.getNumberingSystems()。该选项也可以通过 nu Unicode 扩展键设置;如果两者都提供,则此 options 属性优先。

款式选择

¥Style options

根据所使用的 style,其中一些可能会被忽略,而另一些可能是必需的:

¥Depending on the style used, some of them may be ignored, and others may be required:

style

要使用的格式样式。

"decimal"(默认)

用于纯数字格式。

"currency"

用于货币格式。

"percent"

用于百分比格式。

"unit"

用于单位格式化。

currency

货币格式中使用的货币。可能的值是 ISO 4217 货币代码,例如 "USD" 代表美元,"EUR" 代表欧元,"CNY" 代表人民币 - 请参阅 当前货币和基金代码列表。没有默认值;如果 style"currency",则必须提供 currency 属性。

currencyDisplay

如何以货币格式显示货币。

"code"

使用 ISO 货币代码。

"symbol"(默认)

使用本地化货币符号,例如 €。

"narrowSymbol"

使用窄格式符号("$100" 而不是 "US$100")。

"name"

使用本地化货币名称,例如 "dollar"

currencySign

在许多语言环境中,记帐格式意味着用括号将数字括起来,而不是附加减号。可能的值为 "standard""accounting";默认为 "standard"

unit

unit 格式中使用的单位,可能的值是核心单位标识符,在 UTS #35,第 2 部分,第 6 节 中定义。从 完整列表 中选择了 subset 个单元用于 ECMAScript。成对的简单单元可以用 "-每-" 连接起来形成一个复合单元。没有默认值;如果 style"unit",则必须提供 unit 属性。

unitDisplay

unit 格式中使用的单位格式样式。可能的值为:

"short"(默认)

例如,16 l

"narrow"

例如,16l

"long"

例如,16 litres

数字选项

¥Digit options

Intl.PluralRules 还支持以下属性。

¥The following properties are also supported by Intl.PluralRules.

minimumIntegerDigits

要使用的最小整数位数。格式化时,整数位数少于此数字的值将在左侧填充零(至指定长度)。可能的值是从 121;默认为 1

minimumFractionDigits

要使用的最小小数位数。可能的值是从 020;纯数字和百分比格式的默认值是 0;货币格式的默认值是 ISO 4217 货币代码表 提供的小单位位数(如果列表未提供该信息,则为 2)。

maximumFractionDigits

要使用的最大小数位数。可能的值是从 020;纯数字格式的默认值是 minimumFractionDigits3 中较大的一个;货币格式的默认值是 minimumFractionDigitsISO 4217 货币代码表 提供的小单位位数中的较大者(如果列表未提供该信息,则为 2);百分比格式的默认值是 minimumFractionDigits 和 0 中的较大者。

minimumSignificantDigits

要使用的最小有效数字位数。可能的值是从 121;默认为 1

maximumSignificantDigits

要使用的最大有效数字位数。可能的值是从 121;默认为 21

上述属性分为两组:minimumIntegerDigitsminimumFractionDigitsmaximumFractionDigits 为一组,minimumSignificantDigitsmaximumSignificantDigits 为另一组。如果指定了两个组的属性,则结果显示格式中的冲突将根据 roundingPriority 属性的值解决。

¥The above properties fall into two groups: minimumIntegerDigits, minimumFractionDigits, and maximumFractionDigits in one group, minimumSignificantDigits and maximumSignificantDigits in the other. If properties from both groups are specified, conflicts in the resulting display format are resolved based on the value of the roundingPriority property.

roundingPriority

指定如果同时指定了 "FractionDigits" (minimumFractionDigits/maximumFractionDigits) 和 "SignificantDigits" (minimumSignificantDigits/maximumSignificantDigits),将如何解决舍入冲突。可能的值为:

"auto"(默认)

使用有效数字属性的结果。

"morePrecision"

使用导致更精确的属性的结果。

"lessPrecision"

使用导致精度较低的属性的结果。

请注意,对于 auto 以外的值,更精确的结果是根据 maximumSignificantDigitsmaximumFractionDigits 计算的(忽略最小小数和有效数字设置)。

roundingIncrement

表示相对于计算的舍入幅度应进行舍入的增量。可能的值为 125102025501002002505001000200025005000。它不能与有效数字舍入或除 auto 之外的任何 roundingPriority 设置混合。

roundingMode

小数点应如何四舍五入。可能的值为:

"ceil"

向+∞舍入。正值向上舍入。"更积极" 轮负值。

"floor"

向-∞舍入。正值向下舍入。"更消极" 轮负值。

"expand"

远离 0 舍入。值的大小总是通过舍入而增加。正值向上舍入。"更消极" 轮负值。

"trunc"

向 0 舍入。该值的大小始终会通过舍入而减小。正值向下舍入。"减少负面影响" 轮负值。

"halfCeil"

关系趋于+∞。高于半增量的值如 "ceil"(朝向 +∞),低于半增量的值如 "floor"(朝向 -∞)。在半增量上,值像 "ceil" 一样舍入。

"halfFloor"

关系趋于-∞。高于半增量的值如 "ceil"(朝向 +∞),低于半增量的值如 "floor"(朝向 -∞)。在半增量上,值像 "floor" 一样舍入。

"halfExpand"(默认)

远离 0 的关系。高于半增量的值如 "expand"(远离零),低于半增量的值如 "trunc"(朝向 0)。在半增量上,值像 "expand" 一样舍入。

"halfTrunc"

与 0 相关。高于半增量的值如 "expand"(远离零),低于半增量的值如 "trunc"(朝向 0)。在半增量上,值像 "trunc" 一样舍入。

"halfEven"

与最接近的偶数联系。高于半增量的值如 "expand"(远离零),低于半增量的值如 "trunc"(朝向 0)。在半增量值上,四舍五入到最接近的偶数位。

这些选项反映了 重症监护病房用户指南,其中 "expand" 和 "trunc" 分别映射到 ICU "UP" 和 "DOWN"。下面的 舍入模式 示例演示了每种模式的工作原理。

trailingZeroDisplay

在整数上显示尾随零的策略。可能的值为:

"auto"(默认)

根据 minimumFractionDigitsminimumSignificantDigits 保留尾随零。

"stripIfInteger"

如果小数位全为零,则去掉小数位。如果任何小数位非零,则与 "auto" 相同。

其他选项

¥Other options

notation

应为数字显示的格式。可能的值为:

"standard"(默认)

普通数字格式。

"scientific"

返回格式化数字的数量级。

"engineering"

返回 10 能被 3 整除的指数。

"compact"

表示指数的字符串;默认使用 "short" 形式。

compactDisplay

仅当 notation"compact" 时使用。可能的值为 "short""long";默认为 "short"

useGrouping

是否使用分组分隔符,例如千位分隔符或千/十/千万分隔符。

"always"

即使语言环境偏好其他方式,也显示分组分隔符。

"auto"

根据区域设置首选项显示分组分隔符,这也可能取决于货币。

"min2"

当组中至少有 2 位数字时显示分组分隔符。

true

"always" 相同。

false

不显示分组分隔符。

如果 notation"compact",则默认为 "min2",否则默认为 "auto"。接受字符串值 "true""false",但始终会转换为默认值。

signDisplay

何时显示号码的符号。可能的值为:

"auto"(默认)

仅显示负数的符号,包括负零。

"always"

始终显示标志。

"exceptZero"

显示正数和负数的符号,但不显示零。

"negative"

仅显示负数的符号,不包括负零。

"never"

切勿展示标志。

返回值

¥Return value

一个新的 Intl.NumberFormat 对象。

¥A new Intl.NumberFormat object.

注意:下面的文本描述了规范标记为 "optional" 的行为。它可能不适用于所有环境。检查 浏览器兼容性表

¥Note: The text below describes behavior that is marked by the specification as "optional". It may not work in all environments. Check the browser compatibility table.

通常,可以在有或没有 new 的情况下调用 Intl.NumberFormat(),并且在这两种情况下都会返回一个新的 Intl.NumberFormat 实例。但是,如果 this 值是一个 instanceof Intl.NumberFormat 的对象(并不一定意味着它是通过 new Intl.NumberFormat 创建的;只是它的原型链中有 Intl.NumberFormat.prototype),则返回 this 的值,以及新创建的 Intl.NumberFormat 对象 隐藏在 [Symbol(IntlLegacyConstructedSymbol)] 属性中(在实例之间重复使用的唯一符号)。

¥Normally, Intl.NumberFormat() can be called with or without new, and a new Intl.NumberFormat instance is returned in both cases. However, if the this value is an object that is instanceof Intl.NumberFormat (doesn't necessarily mean it's created via new Intl.NumberFormat; just that it has Intl.NumberFormat.prototype in its prototype chain), then the value of this is returned instead, with the newly created Intl.NumberFormat object hidden in a [Symbol(IntlLegacyConstructedSymbol)] property (a unique symbol that's reused between instances).

js
const formatter = Intl.NumberFormat.call(
  { __proto__: Intl.NumberFormat.prototype },
  "en-US",
  { notation: "scientific" },
);
console.log(Object.getOwnPropertyDescriptors(formatter));
// {
//   [Symbol(IntlLegacyConstructedSymbol)]: {
//     value: NumberFormat [Intl.NumberFormat] {},
//     writable: false,
//     enumerable: false,
//     configurable: false
//   }
// }

请注意,这里只有一个实际的 Intl.NumberFormat 实例:隐藏在 [Symbol(IntlLegacyConstructedSymbol)] 中的那个。在 formatter 上调用 format()resolvedOptions() 方法将正确使用该实例中存储的选项,但调用所有其他方法(例如 formatRange())将失败并显示“TypeError:formatRange 方法在不兼容的对象上调用”,因为这些方法不参考隐藏实例的选项。

¥Note that there's only one actual Intl.NumberFormat instance here: the one hidden in [Symbol(IntlLegacyConstructedSymbol)]. Calling the format() and resolvedOptions() methods on formatter would correctly use the options stored in that instance, but calling all other methods (e.g. formatRange()) would fail with "TypeError: formatRange method called on incompatible Object", because those methods don't consult the hidden instance's options.

当在没有 new 的情况下调用 Intl.NumberFormat() 但将 this 设置为除 instanceof Intl.NumberFormat 之外的任何其他值时,不会发生这种称为 ChainNumberFormat 的行为。如果直接调用为 Intl.NumberFormat(),则 this 值为 Intl,正常创建新的 Intl.NumberFormat 实例。

¥This behavior, called ChainNumberFormat, does not happen when Intl.NumberFormat() is called without new but with this set to anything else that's not an instanceof Intl.NumberFormat. If you call it directly as Intl.NumberFormat(), the this value is Intl, and a new Intl.NumberFormat instance is created normally.

例外情况

¥Exceptions

RangeError

有下列情况之一的,抛出:

  • 采用枚举值(例如 styleunitscurrency 等)的属性被设置为无效值。
  • maximumFractionDigitsminimumFractionDigits 都设置了,并且设置为不同的值。请注意,根据各种格式选项,这些属性可以具有默认值。因此,即使你只设置其中一个属性,也可能会出现此错误。
TypeError

如果 options.style 属性设置为 "unit" 或 "currency",并且尚未为相应属性 options.unitoptions.currency 设置值,则抛出该错误。

示例

¥Examples

基本用法

¥Basic usage

在不指定区域设置的基本使用中,将返回默认区域设置和带有默认选项的格式化字符串。

¥In basic use without specifying a locale, a formatted string in the default locale and with default options is returned.

js
const amount = 3500;

console.log(new Intl.NumberFormat().format(amount));
// '3,500' if in US English locale

小数和百分比格式

¥Decimal and percent formatting

js
const amount = 3500;

new Intl.NumberFormat("en-US", {
  style: "decimal",
}).format(amount); // '3,500'
new Intl.NumberFormat("en-US", {
  style: "percent",
}).format(amount); // '350,000%'

单位格式

¥Unit formatting

如果 style'unit',则必须提供 unit 属性。(可选)unitDisplay 控制单位格式。

¥If the style is 'unit', a unit property must be provided. Optionally, unitDisplay controls the unit formatting.

js
const amount = 3500;

new Intl.NumberFormat("en-US", {
  style: "unit",
  unit: "liter",
}).format(amount); // '3,500 L'

new Intl.NumberFormat("en-US", {
  style: "unit",
  unit: "liter",
  unitDisplay: "long",
}).format(amount); // '3,500 liters'

货币格式

¥Currency formatting

如果 style'currency',则必须提供 currency 属性。或者,currencyDisplaycurrencySign 控制单元格式。

¥If the style is 'currency', a currency property must be provided. Optionally, currencyDisplay and currencySign control the unit formatting.

js
const amount = -3500;
new Intl.NumberFormat("en-US", {
  style: "currency",
  currency: "USD",
}).format(amount); // '-$3,500.00'

new Intl.NumberFormat("bn", {
  style: "currency",
  currency: "USD",
  currencyDisplay: "name",
}).format(amount); // '-3,500.00 US dollars'

new Intl.NumberFormat("bn", {
  style: "currency",
  currency: "USD",
  currencySign: "accounting",
}).format(amount); // '($3,500.00)'

科学、工程或紧凑符号

¥Scientific, engineering or compact notations

科学和紧凑表示法由 notation 选项表示,格式如下:

¥Scientific and compact notation are represented by the notation option and can be formatted like this:

js
new Intl.NumberFormat("en-US", {
  notation: "scientific",
}).format(987654321);
// 9.877E8

new Intl.NumberFormat("pt-PT", {
  notation: "scientific",
}).format(987654321);
// 9,877E8

new Intl.NumberFormat("en-GB", {
  notation: "engineering",
}).format(987654321);
// 987.654E6

new Intl.NumberFormat("de", {
  notation: "engineering",
}).format(987654321);
// 987,654E6

new Intl.NumberFormat("zh-CN", {
  notation: "compact",
}).format(987654321);
// 9.9亿

new Intl.NumberFormat("fr", {
  notation: "compact",
  compactDisplay: "long",
}).format(987654321);
// 988 millions

new Intl.NumberFormat("en-GB", {
  notation: "compact",
  compactDisplay: "short",
}).format(987654321);
// 988M

展示标志

¥Displaying signs

显示正数和负数的符号,但不显示零:

¥Display a sign for positive and negative numbers, but not zero:

js
new Intl.NumberFormat("en-US", {
  style: "percent",
  signDisplay: "exceptZero",
}).format(0.55);
// '+55%'

请注意,当货币符号为 "accounting" 时,可以使用括号代替减号:

¥Note that when the currency sign is "accounting", parentheses might be used instead of a minus sign:

js
new Intl.NumberFormat("bn", {
  style: "currency",
  currency: "USD",
  currencySign: "accounting",
  signDisplay: "always",
}).format(-3500);
// '($3,500.00)'

小数位数、有效位数和整数位数

¥FractionDigits, SignificantDigits and IntegerDigits

你可以指定在设置数字格式时显示的小数、整数或有效数字的最小或最大数量。

¥You can specify the minimum or maximum number of fractional, integer or significant digits to display when formatting a number.

注意:如果同时指定了有效数字限制和小数数字限制,则实际格式取决于 roundingPriority

¥Note: If both significant and fractional digit limits are specified, then the actual formatting depends on the roundingPriority.

使用 FractionDigits 和 IntegerDigits

¥Using FractionDigits and IntegerDigits

整数和分数数字属性分别指示小数点之前和之后要显示的位数。如果要显示的值的整数位数少于指定的位数,则将在左侧用零填充到预期的数字。如果它的小数位数较少,则会在右侧用零填充。两种情况如下图所示:

¥The integer and fraction digit properties indicate the number of digits to display before and after the decimal point, respectively. If the value to display has fewer integer digits than specified, it will be left-padded with zeros to the expected number. If it has fewer fractional digits, it will be right-padded with zeros. Both cases are shown below:

js
// Formatting adds zeros to display minimum integers and fractions
console.log(
  new Intl.NumberFormat("en", {
    minimumIntegerDigits: 3,
    minimumFractionDigits: 4,
  }).format(4.33),
);
// "004.3300"

如果某个值的小数位数多于指定的最大位数,则会四舍五入。舍入的方式取决于 roundingMode 属性(舍入模式 部分提供了更多详细信息)。下面的值从五个小数位 (4.33145) 舍入到两个小数位 (4.33):

¥If a value has more fractional digits than the specified maximum number, it will be rounded. The way that it is rounded depends on the roundingMode property (more details are provided in the rounding modes section). Below the value is rounded from five fractional digits (4.33145) to two (4.33):

js
// Display value shortened to maximum number of digits
console.log(
  new Intl.NumberFormat("en", {
    maximumFractionDigits: 2,
  }).format(4.33145),
);
// "4.33"

如果值已经超过 2 个小数位,则最小小数位无效:

¥The minimum fractional digits have no effect if the value already has more than 2 fractional digits:

js
// Minimum fractions have no effect if value is higher precision.
console.log(
  new Intl.NumberFormat("en", {
    minimumFractionDigits: 2,
  }).format(4.33145),
);
// "4.331"

警告:请注意默认值,因为即使代码中未指定,它们也可能会影响格式。对于普通值,默认最大数字值为 3,对于货币,默认最大数字值为 2,并且对于其他预定义类型可能有不同的值。

¥Warning: Watch out for default values as they may affect formatting even if not specified in your code. The default maximum digit value is 3 for plain values, 2 for currency, and may have different values for other predefined types.

即使我们没有指定最大位数,上面的格式化值也会四舍五入为 3 位数字!这是因为当我们指定 minimumFractionDigits 时,设置了默认值 maximumFractionDigits,反之亦然。maximumFractionDigitsminimumFractionDigits 的默认值分别是 30

¥The formatted value above is rounded to 3 digits, even though we didn't specify the maximum digits! This is because a default value of maximumFractionDigits is set when we specify minimumFractionDigits, and visa versa. The default values of maximumFractionDigits and minimumFractionDigits are 3 and 0, respectively.

你可以使用 resolvedOptions() 检查格式化程序。

¥You can use resolvedOptions() to inspect the formatter.

js
console.log(
  new Intl.NumberFormat("en", {
    maximumFractionDigits: 2,
  }).resolvedOptions(),
);
// {
//   …
//   minimumIntegerDigits: 1,
//   minimumFractionDigits: 0,
//   maximumFractionDigits: 2,
//   …
// }

console.log(
  new Intl.NumberFormat("en", {
    minimumFractionDigits: 2,
  }).resolvedOptions(),
);
// {
//   …
//   minimumIntegerDigits: 1,
//   minimumFractionDigits: 2,
//   maximumFractionDigits: 3,
//   …
// }

使用有效数字

¥Using SignificantDigits

有效位数是包括整数部分和小数部分的总位数。maximumSignificantDigits 用于指示从原始值开始显示的总位数。

¥The number of significant digits is the total number of digits including both integer and fractional parts. The maximumSignificantDigits is used to indicate the total number of digits from the original value to display.

下面的示例展示了其工作原理。特别注意最后一种情况:仅保留第一位数字,其他数字被丢弃/设置为零。

¥The examples below show how this works. Note in particular the last case: only the first digit is retained and the others are discarded/set to zero.

js
// Display 5 significant digits
console.log(
  new Intl.NumberFormat("en", {
    maximumSignificantDigits: 5,
  }).format(54.33145),
);
// "54.331"

// Max 2 significant digits
console.log(
  new Intl.NumberFormat("en", {
    maximumSignificantDigits: 2,
  }).format(54.33145),
);
// "54"

// Max 1 significant digits
console.log(
  new Intl.NumberFormat("en", {
    maximumSignificantDigits: 1,
  }).format(54.33145),
);
// "50"

minimumSignificantDigits 确保至少显示指定的位数,并根据需要在值末尾添加零。

¥The minimumSignificantDigits ensures that at least the specified number of digits are displayed, adding zeros to the end of the value if needed.

js
// Minimum 10 significant digits
console.log(
  new Intl.NumberFormat("en", {
    minimumSignificantDigits: 10,
  }).format(54.33145),
);
// "54.33145000"

警告:请注意默认值,因为它们可能会影响格式。如果仅使用一个 SignificantDigits 属性,则其对应属性将自动应用默认值。默认最大和最小有效数字值分别为 20 和 1。

¥Warning: Watch out for default values as they may affect formatting. If only one SignificantDigits property is used, then its counterpart will automatically be applied with the default value. The default maximum and minimum significant digit values are 20 and 1, respectively.

同时指定有效数字和小数数字

¥Specifying significant and fractional digits at the same time

小数位 (minimumFractionDigits/maximumFractionDigits) 和有效位 (minimumSignificantDigits/maximumSignificantDigits) 都是控制应格式化多少小数位和前导数字的方法。如果两者同时使用,可能会发生冲突。

¥The fraction digits (minimumFractionDigits/maximumFractionDigits) and significant digits (minimumSignificantDigits/maximumSignificantDigits) are both ways of controlling how many fractional and leading digits should be formatted. If both are used at the same time, it is possible for them to conflict.

这些冲突可使用 roundingPriority 属性解决。默认情况下,其值为 "auto",这意味着如果指定 minimumSignificantDigitsmaximumSignificantDigits,则将忽略小数和整数数字属性。

¥These conflicts are resolved using the roundingPriority property. By default, this has a value of "auto", which means that if either minimumSignificantDigits or maximumSignificantDigits is specified, the fractional and integer digit properties will be ignored.

例如,下面的代码将 4.33145 的值格式化为 maximumFractionDigits: 3,然后格式化为 maximumSignificantDigits: 2,最后格式化两者。两者的值为与 maximumSignificantDigits 设定的值。

¥For example, the code below formats the value of 4.33145 with maximumFractionDigits: 3, and then maximumSignificantDigits: 2, and then both. The value with both is the one set with maximumSignificantDigits.

js
console.log(
  new Intl.NumberFormat("en", {
    maximumFractionDigits: 3,
  }).format(4.33145),
);
// "4.331"
console.log(
  new Intl.NumberFormat("en", {
    maximumSignificantDigits: 2,
  }).format(4.33145),
);
// "4.3"
console.log(
  new Intl.NumberFormat("en", {
    maximumFractionDigits: 3,
    maximumSignificantDigits: 2,
  }).format(4.33145),
);
// "4.3"

使用 resolvedOptions() 检查格式化程序,我们可以看到当指定 maximumSignificantDigitsminimumSignificantDigits 时,返回的对象不包含 maximumFractionDigits

¥Using resolvedOptions() to inspect the formatter, we can see that the returned object does not include maximumFractionDigits when maximumSignificantDigits or minimumSignificantDigits are specified.

js
console.log(
  new Intl.NumberFormat("en", {
    maximumFractionDigits: 3,
    maximumSignificantDigits: 2,
  }).resolvedOptions(),
);
// {
//   …
//   minimumIntegerDigits: 1,
//   minimumSignificantDigits: 1,
//   maximumSignificantDigits: 2,
//   …
// }
console.log(
  new Intl.NumberFormat("en", {
    maximumFractionDigits: 3,
    minimumSignificantDigits: 2,
  }).resolvedOptions(),
);
// {
//   …
//   minimumIntegerDigits: 1,
//   minimumSignificantDigits: 2,
//   maximumSignificantDigits: 21,
//   …
// }

除了 "auto" 之外,你还可以通过将 roundingPriority 指定为 "morePrecision""lessPrecision" 来解决冲突。格式化程序使用 maximumSignificantDigitsmaximumFractionDigits 的值计算精度。

¥In addition to "auto", you can resolve conflicts by specifying roundingPriority as "morePrecision" or "lessPrecision". The formatter calculates the precision using the values of maximumSignificantDigits and maximumFractionDigits.

下面的代码显示了为三种不同舍入优先级选择的格式:

¥The code below shows the format being selected for the three different rounding priorities:

js
const maxFracNF = new Intl.NumberFormat("en", {
  maximumFractionDigits: 3,
});
console.log(`maximumFractionDigits:3 - ${maxFracNF.format(1.23456)}`);
// "maximumFractionDigits:2 - 1.235"

const maxSigNS = new Intl.NumberFormat("en", {
  maximumSignificantDigits: 3,
});
console.log(`maximumSignificantDigits:3 - ${maxSigNS.format(1.23456)}`);
// "maximumSignificantDigits:3 - 1.23"

const bothAuto = new Intl.NumberFormat("en", {
  maximumSignificantDigits: 3,
  maximumFractionDigits: 3,
});
console.log(`auto - ${bothAuto.format(1.23456)}`);
// "auto - 1.23"

const bothLess = new Intl.NumberFormat("en", {
  roundingPriority: "lessPrecision",
  maximumSignificantDigits: 3,
  maximumFractionDigits: 3,
});
console.log(`lessPrecision - ${bothLess.format(1.23456)}`);
// "lessPrecision - 1.23"

const bothMore = new Intl.NumberFormat("en", {
  roundingPriority: "morePrecision",
  maximumSignificantDigits: 3,
  maximumFractionDigits: 3,
});
console.log(`morePrecision - ${bothMore.format(1.23456)}`);
// "morePrecision - 1.235"

请注意,如果指定了最小值而没有指定最大值,则该算法的行为可能会不直观。下面的示例格式化值 1,指定 minimumFractionDigits: 2(格式化为 1.00)和 minimumSignificantDigits: 2(格式化为 1.0)。由于 1.00 的位数比 1.0 多,所以这应该是优先考虑 morePrecision 时的结果,但事实上恰恰相反:

¥Note that the algorithm can behave in an unintuitive way if a minimum value is specified without a maximum value. The example below formats the value 1 specifying minimumFractionDigits: 2 (formatting to 1.00) and minimumSignificantDigits: 2 (formatting to 1.0). Since 1.00 has more digits than 1.0, this should be the result when prioritizing morePrecision, but in fact the opposite is true:

js
const bothLess = new Intl.NumberFormat("en", {
  roundingPriority: "lessPrecision",
  minimumFractionDigits: 2,
  minimumSignificantDigits: 2,
});
console.log(`lessPrecision - ${bothLess.format(1)}`);
// "lessPrecision - 1.00"

const bothMore = new Intl.NumberFormat("en", {
  roundingPriority: "morePrecision",
  minimumFractionDigits: 2,
  minimumSignificantDigits: 2,
});
console.log(`morePrecision - ${bothMore.format(1)}`);
// "morePrecision - 1.0"

原因是仅使用 "最大精度" 值进行计算,而 maximumSignificantDigits 的默认值远高于 maximumFractionDigits

¥The reason for this is that only the "maximum precision" values are used for the calculation, and the default value of maximumSignificantDigits is much higher than maximumFractionDigits.

注意:工作组提出了对算法的修改,其中格式化程序应独立评估使用指定小数和有效数字的结果(考虑最小值和最大值)。然后,如果设置了 morePrecision,它将选择显示更多小数位的选项,如果设置了 lessPrecision,则选择显示更少小数位的选项。对于这种情况,这将导致更直观的行为。

¥Note: The working group have proposed a modification of the algorithm where the formatter should evaluate the result of using the specified fractional and significant digits independently (taking account of both minimum and maximum values). It will then select the option that displays more fractional digits if morePrecision is set, and fewer if lessPrecision is set. This will result in more intuitive behavior for this case.

舍入模式

¥Rounding modes

如果值的小数位数多于构造函数选项允许的小数位数,则格式化值将四舍五入到指定的小数位数。值舍入的方式取决于 roundingMode 属性。

¥If a value has more fractional digits than allowed by the constructor options, the formatted value will be rounded to the specified number of fractional digits. The way in which the value is rounded depends on the roundingMode property.

数字格式化程序默认使用 halfExpand 舍入,即以半增量舍入值 "远离零"(换句话说,值的大小向上舍入)。

¥Number formatters use halfExpand rounding by default, which rounds values "away from zero" at the half-increment (in other words, the magnitude of the value is rounded up).

对于正数,如果要删除的小数位更接近下一个增量(或在中间点),则剩余的小数位将向上舍入,否则将向下舍入。如下所示:2.23 四舍五入到两位有效数字会被截断为 2.2,因为 2.23 小于半增量 2.25,而 2.25 及更大的值会四舍五入到 2.3:

¥For a positive number, if the fractional digits to be removed are closer to the next increment (or on the half way point) then the remaining fractional digits will be rounded up, otherwise they are rounded down. This is shown below: 2.23 rounded to two significant digits is truncated to 2.2 because 2.23 is less than the half increment 2.25, while values of 2.25 and greater are rounded up to 2.3:

js
// Value below half-increment: round down.
console.log(
  new Intl.NumberFormat("en", {
    maximumSignificantDigits: 2,
  }).format(2.23),
);
// "2.2"

// Value on or above half-increment: round up.
console.log(
  new Intl.NumberFormat("en", {
    maximumSignificantDigits: 2,
  }).format(2.25),
);
console.log(
  new Intl.NumberFormat("en", {
    maximumSignificantDigits: 2,
  }).format(2.28),
);
// "2.3"
// "2.3"

半增量点或以下的负数也会从零舍入(变得更负):

¥A negative number on or below the half-increment point is also rounded away from zero (becomes more negative):

js
// Value below half-increment: round down.
console.log(
  new Intl.NumberFormat("en", {
    maximumSignificantDigits: 2,
  }).format(-2.23),
);
// "-2.2"

// Value on or above half-increment: round up.
console.log(
  new Intl.NumberFormat("en", {
    maximumSignificantDigits: 2,
  }).format(-2.25),
);
console.log(
  new Intl.NumberFormat("en", {
    maximumSignificantDigits: 2,
  }).format(-2.28),
);
// "-2.3"
// "-2.3"

下表显示了不同舍入模式对半增量及其附近的正值和负值的影响。

¥The table below show the effect of different rounding modes for positive and negative values that are on and around the half-increment.

舍入模式 2.23 2.25 2.28 -2.23 -2.25 -2.28
ceil 2.3 2.3 2.3 -2.2 -2.2 -2.2
floor 2.2 2.2 2.2 -2.3 -2.3 -2.3
expand 2.3 2.3 2.3 -2.3 -2.3 -2.3
trunc 2.2 2.2 2.2 -2.2 -2.2 -2.2
halfCeil 2.2 2.3 2.3 -2.2 -2.2 -2.3
halfFloor 2.2 2.2 2.3 -2.2 -2.3 -2.3
halfExpand 2.2 2.3 2.3 -2.2 -2.3 -2.3
halfTrunc 2.2 2.2 2.3 -2.2 -2.2 -2.3
halfEven 2.2 2.2 2.3 -2.2 -2.2 -2.3

使用 halfEven 时,其行为还取决于四舍五入数最后一位的奇偶校验(奇数或偶数)。例如,上表中 halfEven 的行为与 halfTrunc 相同,因为所有数字的大小都在较小的 "even" 数字 (2.2) 和较大的 "odd" 数字 (2.3) 之间。如果数字在 ±2.3 和 ±2.4 之间,则 halfEven 的行为将与 halfExpand 类似。此行为可以避免在大数据样本中持续低估或高估半增量。

¥When using halfEven, its behavior also depends on the parity (odd or even) of the last digit of the rounded number. For example, the behavior of halfEven in the table above is the same as halfTrunc, because the magnitudes of all numbers are between a smaller "even" number (2.2) and a larger "odd" number (2.3). If the numbers are between ±2.3 and ±2.4, halfEven will behave like halfExpand instead. This behavior avoids consistently under- or over-estimating half-increments in a large data sample.

使用舍入增量

¥Using roundingIncrement

有时我们想将剩余的小数位四舍五入为下一个整数之外的其他增量。例如,最小硬币为 5 美分的货币可能希望将值四舍五入为增量 5,以反映实际可以用现金支付的金额。

¥Sometimes we want to round the remaining fractional digits to some other increment than the next integer. For example, currencies for which the smallest coin is 5 cents might want to round the value to increments of 5, reflecting amounts that can actually be paid in cash.

这种舍入可以通过 roundingIncrement 属性来实现。

¥This kind of rounding can be achieved with the roundingIncrement property.

例如,如果 maximumFractionDigits 为 2,roundingIncrement 为 5,则该数字将四舍五入到最接近的 0.05:

¥For example, if maximumFractionDigits is 2 and roundingIncrement is 5, then the number is rounded to the nearest 0.05:

js
const nf = new Intl.NumberFormat("en-US", {
  style: "currency",
  currency: "USD",
  maximumFractionDigits: 2,
  roundingIncrement: 5,
});

console.log(nf.format(11.29)); // "$11.30"
console.log(nf.format(11.25)); // "$11.25"
console.log(nf.format(11.22)); // "$11.20"

这种特殊图案被称为 "镍舍入",其中镍是美国 5 分硬币的俗称。要四舍五入到最接近的 10 美分 ("一毛钱四舍五入"),你可以将 roundingIncrement 更改为 10

¥This particular pattern is referred to as "nickel rounding", where nickel is the colloquial name for a USA 5 cent coin. To round to the nearest 10 cents ("dime rounding"), you could change roundingIncrement to 10.

js
const nf = new Intl.NumberFormat("en-US", {
  style: "currency",
  currency: "USD",
  maximumFractionDigits: 2,
  roundingIncrement: 5,
});

console.log(nf.format(11.29)); // "$11.30"
console.log(nf.format(11.25)); // "$11.25"
console.log(nf.format(11.22)); // "$11.20"

你还可以使用 roundingMode 更改舍入算法。下面的示例显示了如何使用 halfCeil 舍入将值 "不太积极" 舍入到半舍入增量以下,如果高于半增量则将 "更积极" 舍入。递增的数字是 "0.05",因此半增量为 0.025(下面显示为 11.225)。

¥You can also use roundingMode to change the rounding algorithm. The example below shows how halfCeil rounding can be used to round the value "less positive" below the half-rounding increment and "more positive" if above or on the half-increment. The incremented digit is "0.05" so the half-increment is at .025 (below, this is shown at 11.225).

js
const nf = new Intl.NumberFormat("en-US", {
  style: "currency",
  currency: "USD",
  maximumFractionDigits: 2,
  roundingIncrement: 5,
  roundingMode: "halfCeil",
});

console.log(nf.format(11.21)); // "$11.20"
console.log(nf.format(11.22)); // "$11.20"
console.log(nf.format(11.224)); // "$11.20"
console.log(nf.format(11.225)); // "$11.25"
console.log(nf.format(11.23)); // "$11.25"

如果需要更改位数,请记住 minimumFractionDigitsmaximumFractionDigits 必须设置为相同的值,否则会抛出 RangeError

¥If you need to change the number of digits, remember that minimumFractionDigits and maximumFractionDigits must both be set to the same value, or a RangeError is thrown.

roundingIncrement 不能与有效数字舍入或除 auto 之外的 roundingPriority 的任何设置混合。

¥roundingIncrement cannot be mixed with significant-digits rounding or any setting of roundingPriority other than auto.

规范

Specification
ECMAScript Internationalization API Specification
# sec-intl-numberformat-constructor

¥Specifications

浏览器兼容性

BCD tables only load in the browser

¥Browser compatibility

也可以看看