首页 >web前端 >js教程 >什么是JavaScript国际化API(I18N)?

什么是JavaScript国际化API(I18N)?

Joseph Gordon-Levitt
Joseph Gordon-Levitt原创
2025-02-10 10:52:09192浏览

What is the JavaScript Internationalization API (I18n)?

英语是世界上使用最广泛的语言,但只有七分之一的人说英语。它是3.79亿人的第一语言(母语),但说普通话的人有9.17亿,说西班牙语的人有4.6亿,说印地语的人有3.41亿。

许多非英语使用者居住在新兴市场,这些市场的互联网增长呈指数级增长。如果您的网络应用程序可以进行全球翻译,您的潜在目标市场可能会增加700%!

JavaScript 国际化 API(也称为 i18n)允许您设计网页和应用程序,以便它们可以轻松适应说不同语言的用户的需求。

在本文中,我们将研究 API 提供的各种方法以及如何在您的代码中实现它们以覆盖更广泛的国际受众。

关键要点

  • JavaScript 国际化 API (i18n) 通过支持各种语言和文化规范,促进了网络应用程序对全球受众的适应。
  • 利用 Intl 对象,开发人员可以根据本地偏好格式化日期、时间、数字和列表,这些偏好可能因地区而异。
  • API 包括 Intl.DateTimeFormat()Intl.NumberFormat() 等函数,这些函数接受区域设置标识符以用户熟悉的格式呈现信息。
  • 高级功能,如相对时间格式化 (Intl.RelativeTimeFormat) 和复数敏感格式化 (Intl.PluralRules),允许更细致和更符合文化规范的应用程序。
  • 尽管具有强大的功能,但 JavaScript Intl API 需要仔细实现才能有效处理语言和文化差异,确保应用程序真正实现国际化。

国际化 (I18n) 可能很棘手

国际化看起来很容易……直到您尝试去做它

基于拉丁语系的语言在表面上可能很相似。例如,请求姓名、电子邮件和日期的表单翻译如下:

  • 西班牙语:nombre、email、fecha
  • 法语:nom、e-mail、date
  • 德语:name、email、datum

Gettext 国际化和本地化系统已经存在了几十年,大多数编程语言都有可用的库。

在更简单的案例中,您可以使用某种标记化形式。例如,取一个包含以下内容的 HTML 模板:

<code><label> for="name"></label>{{ NAME }}>
</code>

当用户将英语设置为其主要语言时,这将动态替换为“name”。不幸的是,这就是您的用户界面问题开始出现的地方:

  1. 同一种语言可能有不同的变体。西班牙语在西班牙的用法与在南美洲的用法并不完全相同。
  2. 一种语言中的词在其他语言中可能长得多。例如,“email”在俄语中翻译为“электронное письмо”。
  3. 文本并不总是从左到右排列。有些是从右到左书写的——例如阿拉伯语、希伯来语、库尔德语和意第绪语。其他语言可以从上到下书写,例如中文、韩文、日文和台湾语。

可以通过将文本保持在最少并采用 CSS 属性(如方向、书写模式和逻辑尺寸)进行布局来解决许多问题。

术语混乱

当您的应用程序需要显示日期、时间、数字、货币或单位时,会产生进一步的混淆。

考虑将日期显示为“12/03/24”。它将被解读为:

  • 使用 MDY 格式的美国居民会将其解读为“2024 年 12 月 3 日”
  • 使用 DMY 格式的欧洲、南美洲和亚洲居民会将其解读为“2024 年 3 月 12 日”,
  • 使用更实用的 YMD 格式的加拿大、中国、日本和匈牙利居民会将其解读为“2012 年 3 月 24 日”。

(请注意,日期分隔符斜杠并非所有语言中都常用!)

数字“1,000”将被解读为:

  • 美国、英国、加拿大、中国和日本的人会将其解读为“一千”,
  • 西班牙、法国、德国和俄罗斯的人会将其解读为“一(点零)”,因为这些国家/地区的数字小数部分由逗号分隔。

即使仅在英语中,情况也可能很复杂。“1,000 米”这个术语表示:

  • 对美国居民来说是 1 公里(或 0.62 英里)
  • 对英国、加拿大和澳大利亚的人来说是一千个测量仪器的集合!

JavaScript Intl API

鲜为人知的 JavaScript Intl 对象在大多数现代浏览器和运行时中实现了 ECMAScript 国际化 API。支持通常很好,甚至 IE11 也具有许多更有用的方法。对于旧版浏览器,有一个 polyfill,并且可以像这样检测 API:

<code><label> for="name"></label>{{ NAME }}>
</code>

API 有点不寻常。它为日期、时间、数字和列表提供了一些对象构造函数,这些构造函数传递区域设置和包含配置参数的可选对象。例如,这是一个指定美国英语的 DateTime 对象:

<code>if (window.Intl) {
  // Intl 受支持
}
</code>

此对象可以多次用于调用传递 Date() 值(或可用的 ES6 Temporal)的各种方法。format 方法通常是最实用的选项。例如:

<code>const dateFormatter = new Intl.DateTimeFormat('en-US');
</code>

或者,您可以在一行代码中创建 Intl 对象并运行方法:

<code>const valentinesDay = dateFormatter.format( new Date('2022-02-14') );
// 返回美国格式“2/14/2022”

const starwarsDay = dateFormatter.format( new Date('2022-05-04') );
// 返回美国格式“5/4/2022”
</code>

除了 format() 方法外,某些对象还支持以下方法:

  • formatToParts(): 返回一个包含格式化字符串的对象数组,例如 { type: 'weekday', value: 'Monday' }
  • resolvedOptions(): 返回一个新对象,其中包含反映所用区域设置和格式化选项的属性,例如 dateFormatter.resolvedOptions().locale。

定义区域设置

所有 Intl 对象都需要一个区域设置参数。这是一个字符串,它标识:

  • 语言子标签
  • 脚本子标签(可选)
  • 地区(或国家/地区)子标签(可选)
  • 一个或多个变体子标签(可选)
  • 一个或多个 BCP 47 扩展序列(可选)
  • 专用用途扩展序列(可选)

语言和地区通常就足够了。例如,“en-US”、“fr-FR”等等。

除了使用字符串外,还可以使用 Intl.locale 对象来构造区域设置,例如使用 12 小时时间格式的美国英语:

<code><label> for="name"></label>{{ NAME }}>
</code>

这可以在另一个 Intl 构造函数中使用。例如:

<code>if (window.Intl) {
  // Intl 受支持
}
</code>

如果未定义区域设置,则使用设备的当前语言和地区设置。例如:

<code>const dateFormatter = new Intl.DateTimeFormat('en-US');
</code>

这在使用美国设置的设备上返回“5/4/2022”,在使用英国设置的设备上返回“04/05/2022”。

日期和时间

以下工具显示了使用 Intl.DateTimeFormat() 格式化的日期和时间的示例(如果您的语言或地区未列出,我们深感抱歉!):

(此处应嵌入CodePen示例,但由于我无法直接嵌入外部资源,我只能提供文字描述。) CodePen示例展示了使用Intl.DateTimeFormat()格式化不同地区和语言的日期和时间的多种方法,包括不同的日期样式(full, long, medium, short)和时间样式(full, long, medium, short),以及其他选项例如calendar, timeZone等。

构造函数传递区域设置和选项对象。这有很多可能的属性,尽管您很少需要超过 dateStyle 和/或 timeStyle:

(此处应为表格,但由于我无法直接创建表格,我只能提供文字描述。) 表格列出了Intl.DateTimeFormat()的属性及其描述,包括dateStyle, timeStyle, calendar, dayPeriod, numberingSystem, localeMatcher, timeZone, hour12, hourCycle, formatMatcher, weekday, era, year, month, day, hour, minute, second, timeZoneName等。

示例:

<code>const valentinesDay = dateFormatter.format( new Date('2022-02-14') );
// 返回美国格式“2/14/2022”

const starwarsDay = dateFormatter.format( new Date('2022-05-04') );
// 返回美国格式“5/4/2022”
</code>

日期范围

formatRange() 方法采用两个日期并以最简洁的方式格式化期间,具体取决于区域设置和选项。例如:

<code>const starwarsDay = new Intl.DateTimeFormat('en-US').format( new Date('2022-05-04') );
</code>

此方法的浏览器支持范围较小,但在 Chrome 76 中已实现。

相对期间

Intl.RelativeTimeFormat() 对象可以显示相对于此时此刻的期间。选项对象具有较少的选项:

(此处应为表格,但由于我无法直接创建表格,我只能提供文字描述。) 表格列出了Intl.RelativeTimeFormat()的属性及其描述,包括localeMatcher, numeric, style等。

format() 方法传递数值和单位:“year”、“quarter”、“month”、“week”、“day”、“hour”、“minute”或“second”。示例:

<code><label> for="name"></label>{{ NAME }}>
</code>

数字、货币、百分比和单位

以下工具显示了使用 Intl.NumberFormat() 格式化数字、货币、百分比和测量单位的示例:

(此处应嵌入CodePen示例,但由于我无法直接嵌入外部资源,我只能提供文字描述。) CodePen示例展示了使用Intl.NumberFormat()格式化不同地区和语言的数字、货币、百分比和单位,包括不同的样式(decimal, currency, percent, unit)和选项例如notation, currency, currencyDisplay, unit, unitDisplay, useGrouping, minimumIntegerDigits, minimumFractionDigits, maximumFractionDigits, minimumSignificantDigits, maximumSignificantDigits等。

构造函数传递区域设置和选项对象:

(此处应为表格,但由于我无法直接创建表格,我只能提供文字描述。) 表格列出了Intl.NumberFormat()的属性及其描述,包括numberingSystem, notation, style, currency, currencyDisplay, currencySign, unit, unitDisplay, useGrouping, minimumIntegerDigits, minimumFractionDigits, maximumFractionDigits, minimumSignificantDigits, maximumSignificantDigits等。

示例:

<code>if (window.Intl) {
  // Intl 受支持
}
</code>

列表

Intl.ListFormat() 对象可以将项目数组格式化为对语言敏感的列表。在英语中,这通常需要在最后一个项目之前添加“and”或“or”。

选项对象可以设置以下属性:

(此处应为表格,但由于我无法直接创建表格,我只能提供文字描述。) 表格列出了Intl.ListFormat()的属性及其描述,包括type, style等。

示例:

<code>const dateFormatter = new Intl.DateTimeFormat('en-US');
</code>

复数

稍微奇怪的 Intl.PluralRules() 对象支持复数敏感语言规则,其中您有多个项目。选项对象可以将 type 属性设置为:

  • 基数:事物的数量(默认值),或
  • 序数:事物的排名,例如英语中的第一、第二或第三

select() 方法返回表示数字复数类别(零、一、二、少数、多数或其他)的英语字符串。

示例:

<code><label> for="name"></label>{{ NAME }}>
</code>

字符串比较

最后,Intl.Collator() 对象支持对语言敏感的字符串比较。其选项对象可以设置以下属性:

(此处应为表格,但由于我无法直接创建表格,我只能提供文字描述。) 表格列出了Intl.Collator()的属性及其描述,包括collation, numeric等。

compare() 方法比较两个字符串。例如:

<code>if (window.Intl) {
  // Intl 受支持
}
</code>

利润!

如果您使用 JavaScript 显示数据,则应该可以直接使用用户的本地格式显示信息。例如,以下代码定义了一个 dateFormat() 函数,该函数使用 Intl 短日期格式,或者在不支持该格式时回退到 YYYY-MM-DD

<code>const dateFormatter = new Intl.DateTimeFormat('en-US');
</code>

这本身并不会使您的应用程序易于国际受众使用,但它是更接近全球分发的第一步。

关于 JavaScript 国际化 API (i18n) 的常见问题解答 (FAQ)

JavaScript 国际化 API (i18n) 的目的是什么?

JavaScript 国际化 API(也称为 i18n)是一个内置的 JavaScript API,它提供对语言敏感的字符串比较、数字格式化以及日期和时间格式化。它允许开发人员通过提供对不同语言和文化约定的支持来使他们的应用程序国际化。这对于在全球范围内使用的应用程序特别有用,因为它允许它们适应不同地区的语言和格式约定。

JavaScript i18n 如何处理日期和时间格式化?

JavaScript i18n 提供了一个 DateTimeFormat 对象,可用于根据不同的文化约定格式化日期和时间。此对象将区域设置和选项对象作为参数,它们定义要使用的格式约定。选项对象可以指定日期、时间、时区以及日期和时间格式的其他方面的格式。

JavaScript i18n 如何处理数字格式化?

JavaScript i18n 提供了一个 NumberFormat 对象,可用于根据不同的文化约定格式化数字。此对象将区域设置和选项对象作为参数,它们定义要使用的格式约定。选项对象可以指定数字的样式(十进制、百分比或货币)、分组分隔符的使用、最小和最大小数位数以及数字格式的其他方面。

JavaScript i18n 如何处理字符串比较?

JavaScript i18n 提供了一个 Collator 对象,可用于根据不同的文化约定比较字符串。此对象将区域设置和选项对象作为参数,它们定义要使用的比较约定。选项对象可以指定比较的敏感性(基本、重音、大小写或变体)、数字排序的使用以及字符串比较的其他方面。

如何为 JavaScript i18n 指定区域设置?

创建 DateTimeFormat、NumberFormat 或 Collator 对象时,可以将区域设置指定为参数。区域设置是一个表示语言和地区的字符串,例如美国英语的“en-US”或法国使用的法语的“fr-FR”。如果未指定区域设置,则使用 JavaScript 环境的默认区域设置。

我可以将多个区域设置与 JavaScript i18n 一起使用吗?

是的,创建 DateTimeFormat、NumberFormat 或 Collator 对象时,可以将多个区域设置指定为数组。JavaScript i18n 将使用数组中它支持的第一个区域设置。这对于在多个地区使用的应用程序非常有用,因为它允许它们适应不同地区的语言和格式约定。

如何自定义 JavaScript i18n 的格式化选项?

创建 DateTimeFormat、NumberFormat 或 Collator 对象时,可以通过提供选项对象来自定义 JavaScript i18n 的格式化选项。选项对象可以指定格式化或比较的各个方面,例如日期或数字的格式、字符串比较的敏感性等等。

我可以将 JavaScript i18n 与其他 JavaScript API 一起使用吗?

是的,JavaScript i18n 可以与其他 JavaScript API 结合使用。例如,您可以将 Date 对象与 DateTimeFormat 对象一起使用以格式化日期,或者您可以将 Number 对象与 NumberFormat 对象一起使用以格式化数字。这允许您充分利用 JavaScript 的强大功能来使您的应用程序国际化。

所有浏览器都支持 JavaScript i18n 吗?

大多数现代浏览器(包括 Chrome、Firefox、Safari 和 Edge)都支持 JavaScript i18n。但是,旧版浏览器或某些移动浏览器可能不支持它。您可以查看 Mozilla 开发者网络 (MDN) 上的兼容性表,以获取有关浏览器支持的最新信息。

我在哪里可以了解更多关于 JavaScript i18n 的信息?

您可以从官方 ECMAScript 国际化 API 规范、Mozilla 开发者网络 (MDN) 以及各种在线教程和文章中了解更多关于 JavaScript i18n 的信息。这些资源提供了有关 API 及其用法的详细信息,以及使 JavaScript 应用程序国际化的示例和最佳实践。

以上是什么是JavaScript国际化API(I18N)?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn