Web 平台 API / Intl · 浏览器内置的本地化引擎 / 共同形态:new Intl.X(locales, options) 待审核 1 / 9
shape · 共同形态

共同形态:new Intl.X(locales, options)

Intl 下共有十个构造器,其中九个结构高度一致:用 locale(给谁看)和 options(想要什么形式)构造一个可复用的对象,再反复调它的 .format() / .select() / .compare() / .of() / .segment()。第十个是 Intl.Locale,它不产出文本、也没有这类取值方法,是这一家的异类。先理解这个共同骨架,其余各页只是更换 options。

1 · 骨架:构造一次与多次复用

图 1-1 · 构造一次、多次复用的骨架示意。

构造器接收的第一参数 locales 可以是一个字符串一个数组(按优先级排,挑第一个支持的);不传则用浏览器默认 locale。第二参数 options 是个普通对象,各 API 认的字段不同。返回的格式化器是不可变、可复用的(它持有已解析的 options,并非无状态)——同样的 (locale, options) 别在循环里反复 new

2 · locale 串怎么读:BCP-47 分段

locale 是一串用 - 连接的标签(BCP-47)。点下面任意一段看含义:

图 2-1 · BCP-47 locale 串的分段解剖,可点任一段查看其含义。

-u- 是 Unicode 扩展:把本地化偏好直接写进 locale 串,免去 options。常见键:nu(数字系统,如 hanidec 汉字数字、arab 阿拉伯数字)、ca(历法 chinese/buddhist)、co(排序 pinyin/stroke)、hch12/h23 小时制)。例如 zh-u-nu-hanidec 让数字显示成「一二三」。

3 · 同一个骨架下的九个 API

选一个 locale 和 API,看「同一套写法」如何套到每个子 API 上,并看它实际跑出什么:

图 3-1 · 同一套写法套用到各子 API 上的效果对照。

4 · locale 协商与回退

请求一串 locale,运行时按某种算法挑一个真正支持的,挑不到就一路 fallbackzh-Hant-HKzh-Hant → … → 默认)。用哪种算法由 option localeMatcher 决定(lookup / best fit,见下)。resolvedOptions().locale 告诉最终选中谁,supportedLocalesOf() 告诉一串里哪些被支持:

图 4-1 · locale 协商过程:请求串按算法逐一匹配,挑不到则一路回退到默认 locale。

localeMatcher 是这九个构造器(及各自的 supportedLocalesOf)都认的 option(Intl.Locale 既不读它,也没有 supportedLocalesOfresolvedOptions),决定用哪种协商算法:'lookup' 是 BCP-47(RFC 4647)定义的严格算法,只逐段截断回退(zh-Hant-HKzh-Hantzh);'best fit'默认)是实现自定义的「最佳匹配」,允许挑一个 lookup 不会选、但体验更接近的 locale。实际差异比想象中小:V8 上两种算法在绝大多数输入上给出相同结果——实测 de-CHzh-TWzh-Hant-HK 在两种 matcher 下都原样命中(Node 26 / ICU 78.3 与 Chrome 151 一致,核对于 2026-08)。日常无需指定,保留默认 best fit 即可。

**常见陷阱:**两种失败要分开看。结构合法但不支持时不抛错,静默 fallback 到默认 locale(new Intl.NumberFormat('xx-YY') 即是);结构非法或选项取值非法则抛错——'en_US' 用下划线、localeMatcher: 'bogus' 都抛 RangeError,而 dateStyle 与逐字段混用抛的是 TypeError(均为实测)。想知道「到底用了哪个 locale / 哪些 option 生效」,以 resolvedOptions() 为准,不要靠假设。