Intl.DisplayNames API
将语言、地区、货币和脚本代码转换为可读名称
简介
您的应用拥有国家代码 US,但用户看到的文本是“United States”。您有语言代码 fr,但语言切换器显示为“French”。您有货币代码 EUR,但结账页面显示为“Euro”。
浏览器维护了大量本地化数据,用于以不同语言渲染自身界面。Intl.DisplayNames API 向 JavaScript 暴露这些数据,将标准化代码转换为任何语言下的可读名称。
这样无需第三方库或自定义查找表,也无需额外维护和本地化。浏览器会自动处理数据和翻译。
将地区代码转换为国家名称
最常见的用例是将 ISO 国家代码转换为国家名称。创建一个 DisplayNames 实例,指定 locale 和 type,然后使用国家代码调用 of() 方法:
const regionNames = new Intl.DisplayNames(["en"], { type: "region" });
console.log(regionNames.of("US")); // "United States"
console.log(regionNames.of("GB")); // "United Kingdom"
console.log(regionNames.of("JP")); // "Japan"
第一个参数接受一个符合 BCP 47 标准的 locale 代码数组。浏览器会使用数组中第一个支持的 locale。type 选项用于指定要转换的代码类型。
相同的代码在不同语言下本地化后会产生不同的输出:
const englishRegions = new Intl.DisplayNames(["en"], { type: "region" });
const japaneseRegions = new Intl.DisplayNames(["ja"], { type: "region" });
const spanishRegions = new Intl.DisplayNames(["es"], { type: "region" });
console.log(englishRegions.of("FR")); // "France"
console.log(japaneseRegions.of("FR")); // "フランス"
console.log(spanishRegions.of("FR")); // "Francia"
这种模式适用于构建国家选择器、位置显示以及任何将国家代码转换为可读名称的界面元素。
将语言代码转换为语言名称
语言代码的用法与地区代码相同。设置 type: "language",即可将语言代码转换为语言名称:
const languageNames = new Intl.DisplayNames(["en"], { type: "language" });
console.log(languageNames.of("en")); // "English"
console.log(languageNames.of("es")); // "Spanish"
console.log(languageNames.of("zh")); // "Chinese"
console.log(languageNames.of("ar")); // "Arabic"
语言代码可以包含区域子标签,以表示地区变体:
const languageNames = new Intl.DisplayNames(["en"], { type: "language" });
console.log(languageNames.of("en-US")); // "American English"
console.log(languageNames.of("en-GB")); // "British English"
console.log(languageNames.of("fr-CA")); // "Canadian French"
console.log(languageNames.of("pt-BR")); // "Brazilian Portuguese"
此功能可将语言代码转换为适用于语言切换器、翻译界面和语言偏好选择器的名称。
以本地语言显示语言名称
语言切换器通常以各自的书写系统显示每种语言。请为每个目标语言创建一个单独的 DisplayNames 实例:
const english = new Intl.DisplayNames(["en"], { type: "language" });
const french = new Intl.DisplayNames(["fr"], { type: "language" });
const japanese = new Intl.DisplayNames(["ja"], { type: "language" });
const arabic = new Intl.DisplayNames(["ar"], { type: "language" });
console.log(english.of("en")); // "English"
console.log(french.of("fr")); // "français"
console.log(japanese.of("ja")); // "日本語"
console.log(arabic.of("ar")); // "العربية"
以本地文字显示时,用户能更快识别自己的语言。
货币代码转为货币名称
货币代码遵循 ISO 4217 标准。设置 type: "currency" 可将三字母货币代码转换为货币名称:
const currencyNames = new Intl.DisplayNames(["en"], { type: "currency" });
console.log(currencyNames.of("USD")); // "US Dollar"
console.log(currencyNames.of("EUR")); // "Euro"
console.log(currencyNames.of("GBP")); // "British Pound"
console.log(currencyNames.of("JPY")); // "Japanese Yen"
货币名称会根据显示语言环境进行本地化:
const englishCurrency = new Intl.DisplayNames(["en"], { type: "currency" });
const germanCurrency = new Intl.DisplayNames(["de"], { type: "currency" });
const japaneseCurrency = new Intl.DisplayNames(["ja"], { type: "currency" });
console.log(englishCurrency.of("EUR")); // "Euro"
console.log(germanCurrency.of("EUR")); // "Euro"
console.log(japaneseCurrency.of("EUR")); // "ユーロ"
此模式适用于结账流程中的货币选择器、金融仪表盘和货币转换界面。
脚本代码转为脚本名称
脚本代码采用 ISO 15924 标准。设置 type: "script" 可将四字母脚本代码转换为脚本名称:
const scriptNames = new Intl.DisplayNames(["en"], { type: "script" });
console.log(scriptNames.of("Latn")); // "Latin"
console.log(scriptNames.of("Arab")); // "Arabic"
console.log(scriptNames.of("Cyrl")); // "Cyrillic"
console.log(scriptNames.of("Hans")); // "Simplified Chinese"
console.log(scriptNames.of("Hant")); // "Traditional Chinese"
脚本名称在用户界面中较少出现,但在多语言内容管理系统和区分书写系统的语言选择界面中会用到。
日历代码转为日历名称
不同文化有不同的日历系统。设置 type: "calendar" 可将日历标识符转换为日历名称:
const calendarNames = new Intl.DisplayNames(["en"], { type: "calendar" });
console.log(calendarNames.of("gregory")); // "Gregorian Calendar"
console.log(calendarNames.of("japanese")); // "Japanese Calendar"
console.log(calendarNames.of("buddhist")); // "Buddhist Calendar"
console.log(calendarNames.of("hebrew")); // "Hebrew Calendar"
console.log(calendarNames.of("islamic")); // "Islamic Calendar"
console.log(calendarNames.of("chinese")); // "Chinese Calendar"
这对于排程应用、支持日历系统选择的日期选择器和国际化日历界面非常有用。
日期和时间字段代码转为字段名称
日期和时间界面包含如年、月、日等带标签的字段。设置 type: "dateTimeField" 可将字段标识符转换为本地化字段名称:
const dateFields = new Intl.DisplayNames(["en"], { type: "dateTimeField" });
console.log(dateFields.of("year")); // "year"
console.log(dateFields.of("month")); // "month"
console.log(dateFields.of("day")); // "day"
console.log(dateFields.of("hour")); // "hour"
console.log(dateFields.of("minute")); // "minute"
console.log(dateFields.of("weekday")); // "day of the week"
console.log(dateFields.of("dayPeriod")); // "AM/PM"
console.log(dateFields.of("timeZoneName")); // "time zone"
以下字段名称会根据显示语言进行本地化:
const englishFields = new Intl.DisplayNames(["en"], { type: "dateTimeField" });
const spanishFields = new Intl.DisplayNames(["es"], { type: "dateTimeField" });
const japaneseFields = new Intl.DisplayNames(["ja"], { type: "dateTimeField" });
console.log(englishFields.of("month")); // "month"
console.log(spanishFields.of("month")); // "mes"
console.log(japaneseFields.of("month")); // "月"
有效的字段标识符包括 era、year、quarter、month、weekOfYear、weekday、day、dayPeriod、hour、minute、second 和 timeZoneName。
该模式支持构建可访问性良好的日期选择器、日历界面和时间选择组件,并能正确本地化标签。
通过样式选项控制显示长度
style 选项用于控制输出内容的详细程度。三种取值会产生不同的显示长度:
const longNames = new Intl.DisplayNames(["en"], {
type: "region",
style: "long",
});
const shortNames = new Intl.DisplayNames(["en"], {
type: "region",
style: "short",
});
const narrowNames = new Intl.DisplayNames(["en"], {
type: "region",
style: "narrow",
});
console.log(longNames.of("US")); // "United States"
console.log(shortNames.of("US")); // "US"
console.log(narrowNames.of("US")); // "US"
long 样式(默认)会显示全名。short 和 narrow 样式在可用时会显示缩写形式,但并非所有代码都有简短变体。
当显示语言名称时,样式选项更为重要:
const longLanguages = new Intl.DisplayNames(["en"], {
type: "language",
style: "long",
});
const shortLanguages = new Intl.DisplayNames(["en"], {
type: "language",
style: "short",
});
console.log(longLanguages.of("en-US")); // "American English"
console.log(shortLanguages.of("en-US")); // "US English"
在表单和详细界面中使用 long 以显示完整标签。在移动端导航或空间受限的 UI 元素中,使用 short 或 narrow 以显示紧凑标签。
使用 languageDisplay 处理区域语言变体
带有区域子标签的语言代码可以显示为方言,或以标准语言名加区域说明的形式显示。languageDisplay 选项用于控制此行为,仅在 type: "language" 时生效:
const dialectNames = new Intl.DisplayNames(["en"], {
type: "language",
languageDisplay: "dialect",
});
const standardNames = new Intl.DisplayNames(["en"], {
type: "language",
languageDisplay: "standard",
});
console.log(dialectNames.of("nl-BE")); // "Flemish"
console.log(standardNames.of("nl-BE")); // "Dutch (Belgium)"
console.log(dialectNames.of("en-AU")); // "Australian English"
console.log(standardNames.of("en-AU")); // "English (Australia)"
dialect 值(默认)会用常用名称显示区域变体。standard 值始终以括号形式显示基础语言及区域说明。
当区域变体有用户熟知的名称时,选择 dialect。如需统一格式或处理不常见的语言-区域组合时,选择 standard。
控制无效代码的回退行为
of() 方法接收的代码可能没有对应的显示名称。fallback 选项用于决定如何处理:
const withCodeFallback = new Intl.DisplayNames(["en"], {
type: "region",
fallback: "code",
});
const withNoneFallback = new Intl.DisplayNames(["en"], {
type: "region",
fallback: "none",
});
console.log(withCodeFallback.of("ZZ")); // "ZZ"
console.log(withNoneFallback.of("ZZ")); // undefined
code 值(默认)在没有显示名称时返回输入的代码。none 值会在未映射的代码时返回 undefined。
当你始终需要一个用于显示的字符串值(即使回退为代码本身)时,使用 code。当你需要检测无效代码并显式处理时,使用 none:
const regionNames = new Intl.DisplayNames(["en"], {
type: "region",
fallback: "none",
});
function getRegionName(code) {
const name = regionNames.of(code);
if (name === undefined) {
return "Unknown region";
}
return name;
}
console.log(getRegionName("US")); // "United States"
console.log(getRegionName("INVALID")); // "Unknown region"
构建国家选择器组件
Intl.DisplayNames API 可直接集成到界面组件中。以下示例构建了一个国家选择器,能够以用户的语言显示国家名称:
function CountrySelector({ locale, value, onChange }) {
const regionNames = new Intl.DisplayNames([locale], { type: "region" });
const countries = [
"US",
"GB",
"CA",
"AU",
"FR",
"DE",
"JP",
"CN",
"BR",
"IN",
];
return (
<select value={value} onChange={(e) => onChange(e.target.value)}>
<option value="">Select a country</option>
{countries.map((code) => (
<option key={code} value={code}>
{regionNames.of(code)}
</option>
))}
</select>
);
}
该组件接收一个 locale 属性,用于控制显示语言。更改 locale 属性会重新渲染下拉菜单,并显示翻译后的国家名称。
构建语言切换组件
语言切换器会以各自的书写系统显示每种语言。为每种语言创建一个 DisplayNames 实例:
function LanguageSwitcher({ currentLocale, onLocaleChange }) {
const languages = [
{ code: "en", name: "English" },
{ code: "es", name: "Español" },
{ code: "fr", name: "Français" },
{ code: "de", name: "Deutsch" },
{ code: "ja", name: "日本語" },
{ code: "zh", name: "中文" },
];
return (
<div>
{languages.map((lang) => {
const displayNames = new Intl.DisplayNames([lang.code], {
type: "language",
});
const nativeName = displayNames.of(lang.code);
return (
<button
key={lang.code}
onClick={() => onLocaleChange(lang.code)}
className={currentLocale === lang.code ? "active" : ""}
>
{nativeName}
</button>
);
})}
</div>
);
}
每个按钮都以该语言的书写系统显示语言名称。无论当前界面语言如何,用户都能立即识别自己的语言。
构建货币选择器组件
货币选择器可利用本地化的货币名称。以下示例创建了一个可根据显示语言自适应的货币选择器:
function CurrencySelector({ locale, value, onChange }) {
const currencyNames = new Intl.DisplayNames([locale], { type: "currency" });
const currencies = ["USD", "EUR", "GBP", "JPY", "CNY", "CAD", "AUD"];
return (
<select value={value} onChange={(e) => onChange(e.target.value)}>
<option value="">Select currency</option>
{currencies.map((code) => (
<option key={code} value={code}>
{code} - {currencyNames.of(code)}
</option>
))}
</select>
);
}
下拉菜单会同时显示货币代码和本地化的货币名称。不同地区的用户可以看到本地语言的货币名称。
获取所有支持的值
Intl.supportedValuesOf() 方法会返回每种类型所有支持值的数组,无需维护硬编码的代码列表:
const regions = Intl.supportedValuesOf("region");
console.log(regions); // ["AD", "AE", "AF", "AG", "AI", ...]
const languages = Intl.supportedValuesOf("language");
console.log(languages); // ["aa", "ab", "ae", "af", "ak", ...]
const currencies = Intl.supportedValuesOf("currency");
console.log(currencies); // ["AED", "AFN", "ALL", "AMD", ...]
const calendars = Intl.supportedValuesOf("calendar");
console.log(calendars); // ["buddhist", "chinese", "coptic", ...]
构建动态选择器,自动包含所有支持的值:
function UniversalCountrySelector({ locale, value, onChange }) {
const regionNames = new Intl.DisplayNames([locale], { type: "region" });
const allRegions = Intl.supportedValuesOf("region");
return (
<select value={value} onChange={(e) => onChange(e.target.value)}>
<option value="">Select a country</option>
{allRegions.map((code) => (
<option key={code} value={code}>
{regionNames.of(code)}
</option>
))}
</select>
);
}
该组件会包含浏览器支持的所有区域代码,无需维护硬编码列表。
理解代码格式要求
每种类型都要求代码采用特定格式。格式不正确时,将触发回退行为而不是显示名称。
区域代码遵循 ISO 3166-1 alpha-2(两个字母)或 UN M.49(三位数字):
const regionNames = new Intl.DisplayNames(["en"], { type: "region" });
console.log(regionNames.of("US")); // "United States" (ISO 3166-1)
console.log(regionNames.of("001")); // "world" (UN M.49)
console.log(regionNames.of("150")); // "Europe" (UN M.49)
语言代码遵循 BCP 47,将 ISO 639 语言代码与可选的区域和脚本子标签组合:
const languageNames = new Intl.DisplayNames(["en"], { type: "language" });
console.log(languageNames.of("en")); // "English"
console.log(languageNames.of("en-US")); // "American English"
console.log(languageNames.of("zh-Hans")); // "Simplified Chinese"
console.log(languageNames.of("zh-Hans-CN")); // "Simplified Chinese (China)"
货币代码遵循 ISO 4217(三个字母):
const currencyNames = new Intl.DisplayNames(["en"], { type: "currency" });
console.log(currencyNames.of("USD")); // "US Dollar"
console.log(currencyNames.of("EUR")); // "Euro"
脚本代码遵循 ISO 15924(四个大写字母):
const scriptNames = new Intl.DisplayNames(["en"], { type: "script" });
console.log(scriptNames.of("Latn")); // "Latin"
console.log(scriptNames.of("Arab")); // "Arabic"
代码比较不区分大小写,但按照标准大小写书写可提升可读性:
const regionNames = new Intl.DisplayNames(["en"], { type: "region" });
console.log(regionNames.of("US")); // "United States"
console.log(regionNames.of("us")); // "United States"
console.log(regionNames.of("Us")); // "United States"
浏览器支持与兼容性
Intl.DisplayNames API 自 2021 年起在所有主流浏览器中可用。现代应用可直接使用,无需 polyfill。
基础 API 及 language、region、script 和 currency 类型已获得全面支持。calendar 和 dateTimeField 类型在后续浏览器版本中出现,截至 2025 年已广泛支持。
如有需要,请在运行时检测功能支持情况:
if (typeof Intl.DisplayNames !== "undefined") {
const regionNames = new Intl.DisplayNames(["en"], { type: "region" });
console.log(regionNames.of("US"));
} else {
console.log("Intl.DisplayNames not supported");
}
如需支持旧版浏览器,可在 API 不可用时回退到静态查找表或第三方库。
通过缓存优化性能
创建 DisplayNames 实例的开销极小,但如果应用需要转换大量代码,建议复用实例:
const cache = new Map();
function getDisplayNames(locale, type) {
const key = `${locale}-${type}`;
if (!cache.has(key)) {
cache.set(key, new Intl.DisplayNames([locale], { type }));
}
return cache.get(key);
}
function getCountryName(locale, code) {
const displayNames = getDisplayNames(locale, "region");
return displayNames.of(code);
}
console.log(getCountryName("en", "US")); // "United States"
console.log(getCountryName("en", "FR")); // "France"
console.log(getCountryName("es", "US")); // "Estados Unidos"
缓存会根据 locale 和类型存储实例。后续调用会复用已有实例,而不是新建实例。
这种模式在高频代码路径(如渲染大量本地化数据表格时)尤为重要,因为会涉及数百甚至数千次代码转换。
与其他方法的对比
在 Intl.DisplayNames API 出现之前,应用通常采用多种方式将代码转换为名称。
硬编码查找表需要维护,并且只能支持预设的语言:
const countryNames = {
US: "United States",
GB: "United Kingdom",
FR: "France",
};
function getCountryName(code) {
return countryNames[code] || code;
}
当添加新语言时,这种方式会失效,因为每种语言都需要单独的查找表。
第三方库虽然提供本地化数据,但会增加 bundle 体积:
import countries from "i18n-iso-countries";
import countriesEN from "i18n-iso-countries/langs/en.json";
import countriesES from "i18n-iso-countries/langs/es.json";
countries.registerLocale(countriesEN);
countries.registerLocale(countriesES);
console.log(countries.getName("US", "en")); // "United States"
console.log(countries.getName("US", "es")); // "Estados Unidos"
这些库会为 bundle 增加数 KB 的数据,并且在有新国家或名称变更时需要更新。
Intl.DisplayNames API 解决了这两个问题。浏览器会维护数据,确保其最新,并消除了 bundle 体积的顾虑。数据支持所有浏览器支持的语言,无需额外下载。