聊聊什么是 i18n?JavaScript 中的 i18n 基本概念

简介: 聊聊什么是 i18n?JavaScript 中的 i18n 基本概念

为什么需要 i18n?


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

在互联网呈指数级增长的新兴市场,存在大量非英语用户。如果你的网站可以在全球范围内进行翻译,那么你的潜在目标市场可能会增加 700%!

i18n 全称 Internationalization,也就是国际化的意思,因为单词太长,所以中间的 18 个字母被缩写为 18,再加上开头和结尾的字母,就组成了 i18n。

JavaScript i18n API 可以帮助我们对网站进行多语言翻译,让它们可以轻松适应使用不同语言用户的需求。

在本文中,我将介绍 i18n API 提供的各种方法,以及如何在实际项目中实现 i18n 来覆盖更广泛、更国际化的用户。


i18n 其实很难


从上面的描述中,i18n 看起来很容易,但是当你尝试去做的时候,又发现它并不简单。

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

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

Gettext 是一种在类 Unix 计算机操作系统上实现国际化和本地化程序的系统,它已经存在了几十年,而且这个库可以用在大多数编程语言中,在 nodejs 也可用。

在最简单的场景下,我们可以使用某种形式的标记来实现它。比如下面这段 HTML 模板:


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

当用户将英语设置为主要语言时,NAME 会被动态替换。

但是只是最简单的案例,实际情况中会有很多问题:

  1. 同一种语言可以有不同的变体。在西班牙使用的西班牙语与在南美洲使用的西班牙语不同。
  2. 一种语言中的单词在其他语言中可能会更长。例如,“电子邮件”在俄语中翻译为“электронное письмо”。
  3. 文本并不总是从左到右。有些语言是从右向左书写的,例如阿拉伯语、希伯来语、库尔德语和意第绪语。也有一些语言是可以从上到下书写的,比如中文、韩文、日文和闽南文。


更糟糕的问题


除了上面提到的问题,还有更糟糕的情况。

当我们需要显示日期、时间、数字、货币或单位时,会出现进一步的复杂问题。

在英文中显示其日,通常是 12/03/24 这种格式。但是在其他语言中:

  • 使用 MDY 格式的美国居民会使用 3 December 2024。
  • 使用 DMY 格式的欧洲、南美和亚洲居民会使用 12 March 2024
  • 加拿大、中国、日本和匈牙利居民会使用 2012 年 3 月 24 日,他们选择了实用得多的 YMD 格式。

英文中的数字 1,000,在其他语言中:

  • 美国、英国、加拿大、中国和日本会以千为单位,表示为一千。
  • 西班牙、法国、德国和俄罗斯会表示为一个零点,其中数字的小数部分用逗号分隔。


JavaScript Intl API


其实很多人不知道,在 JavaScript 中存在 Intl 对象

在大多数现代浏览器和运行时中都实现了 ECMAScript 国际化 API,并且兼容性还不错。甚至在 IE11 中也有很多比较有用的方法。

对于较旧的浏览器,还有一个 polyfill 可以用。

Intl API 有点不寻常。它为日期、时间、数字和列表分别提供了几个构造函数,它们会接收一个语言环境和一个包含配置参数的可选对象。

比如,指定美国英语的 DateTime 对象:


const dateFormatter = new Intl.DateTimeFormat('en-US');

这个对象可以被多次调用,传递一个 Date 实例,或者是一个 ES6 Temporal,如果它被支持的话。

format 是最常用也是最实用的方法。它的用法如下:


const valentinesDay = dateFormatter.format(new Date('2022-02-14')); 
// "2/14/2022" 
const starwarsDay = dateFormatter.format(new Date('2022-05-04')); 
// "5/4/2022"

你也可以这么用:


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

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

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


定义语言环境


所有 Intl 对象都需要一个语言环境参数。它是一个字符串,它可以表示以下含义:

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

通常来说,只需要指定语言和地区就足够了。例如,"en-US"、"fr-FR"等。

除了使用字符串外,Intl.locale 对象还可用于构造语言环境,例如具有 12 小时时间格式的美国英语:


const us = new Intl.Locale('en', {
  region: 'US', hourCycle: 'h12', calendar: 'gregory'
});

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


new Intl
  .DateTimeFormat(us, { timeStyle: 'medium' })   
  .format( new Date('2022-05-04T13:00:00') ); 
// "1:00:00 PM"

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


new Intl
  .DateTimeFormat()
  .format( new Date('2022-05-04') );

I18n 的 API 其实比较多,在这里就不再多赘述,更加详细的内容可以参考 MDN 文档

我会在下一篇文章中详细聊聊更详细的业界解决方案。

下一篇:前端 i18n 最佳实践:在 React 中使用 i18next



相关文章
|
1月前
|
机器学习/深度学习 自然语言处理 JavaScript
信息论、机器学习的核心概念:熵、KL散度、JS散度和Renyi散度的深度解析及应用
在信息论、机器学习和统计学领域中,KL散度(Kullback-Leibler散度)是量化概率分布差异的关键概念。本文深入探讨了KL散度及其相关概念,包括Jensen-Shannon散度和Renyi散度。KL散度用于衡量两个概率分布之间的差异,而Jensen-Shannon散度则提供了一种对称的度量方式。Renyi散度通过可调参数α,提供了更灵活的散度度量。这些概念不仅在理论研究中至关重要,在实际应用中也广泛用于数据压缩、变分自编码器、强化学习等领域。通过分析电子商务中的数据漂移实例,展示了这些散度指标在捕捉数据分布变化方面的独特优势,为企业提供了数据驱动的决策支持。
63 2
信息论、机器学习的核心概念:熵、KL散度、JS散度和Renyi散度的深度解析及应用
|
5月前
|
设计模式 JavaScript 前端开发
在JavaScript中,继承是一个重要的概念,它允许我们基于现有的类(或构造函数)创建新的类
【6月更文挑战第15天】JavaScript继承促进代码复用与扩展,创建类层次结构,但过深的继承链导致复杂性增加,紧密耦合增加维护成本,单继承限制灵活性,方法覆盖可能隐藏父类功能,且可能影响性能。设计时需谨慎权衡并考虑使用组合等替代方案。
46 7
|
1月前
|
设计模式 JavaScript 前端开发
探索JavaScript中的闭包:从基础概念到实际应用
在本文中,我们将深入探讨JavaScript中的一个重要概念——闭包。闭包是一种强大的编程工具,它允许函数记住并访问其所在作用域的变量,即使该函数在其作用域之外被调用。通过详细解析闭包的定义、创建方法以及实际应用场景,本文旨在帮助读者不仅理解闭包的理论概念,还能在实际开发中灵活运用这一技巧。
|
1月前
|
存储 JavaScript 前端开发
JavaScript 对象的概念
JavaScript 对象的概念
37 4
|
1月前
|
缓存 JavaScript 前端开发
深入了解JavaScript的闭包:概念与应用
【10月更文挑战第8天】深入了解JavaScript的闭包:概念与应用
|
1月前
|
前端开发 JavaScript 程序员
【从前端入门到全栈】Node.js 之核心概念
【从前端入门到全栈】Node.js 之核心概念
|
1月前
|
缓存 JavaScript 前端开发
Node.js模块化的基本概念和分类及使用方法
Node.js模块化的基本概念和分类及使用方法
32 0
|
1月前
|
自然语言处理 JavaScript 前端开发
深入理解JavaScript中的闭包:概念与应用
【10月更文挑战第8天】深入理解JavaScript中的闭包:概念与应用
|
2月前
|
自然语言处理 JavaScript 前端开发
探索JavaScript中的闭包:从基础概念到实际应用
本文深入探讨了JavaScript中闭包的概念,从定义、作用域链和实际应用等方面进行了详细阐述。通过生动的比喻和实例代码,帮助读者理解闭包在函数执行上下文中的重要性,以及如何在实际开发中有效利用闭包解决复杂问题。同时,文章也指出了过度使用闭包可能导致的潜在问题,并给出了相应的优化建议。
|
3月前
|
JavaScript 前端开发
js bom的概念
js bom的概念
35 1