国际化 API(Intl对象),是 ECMAScript 国际化规范提供的原生工具,用于处理日期、时间、数字、货币、列表、相对时间、复数规则等与语言文化相关的格式化。它的最大优势是无需第三方库,且能自动适配不同地区(locale)的格式习惯,如千位分隔符、日期顺序、货币符号位置等。
下面分模块详细展开,并附上代码示例。
一、Intl对象概述
Intl是一个全局对象,包含多个构造函数和方法,核心有:
Intl.DateTimeFormat:日期时间格式化Intl.NumberFormat:数字(含货币、百分比、科学计数)格式化Intl.RelativeTimeFormat:相对时间(如“3 天前”)Intl.ListFormat:列表格式化(如“A、B 和 C”)Intl.PluralRules:单复数规则Intl.Collator:字符串比较(排序)
每个构造函数接受两个主要参数:
locales:地区标识符字符串或数组,如'zh-CN'、'en-US'、'ja-JP'。可选,默认使用运行环境的默认地区。options:格式化选项对象,控制输出的细节。
二、Intl.DateTimeFormat– 日期时间格式化
基础用法
constdate=newDate('2026-04-28T15:30:00');// 中文(简体中国)格式constdtZh=newIntl.DateTimeFormat('zh-CN');console.log(dtZh.format(date));// "2026/4/28"// 美国英语格式constdtEn=newIntl.DateTimeFormat('en-US');console.log(dtEn.format(date));// "4/28/2026"// 日本格式constdtJa=newIntl.DateTimeFormat('ja-JP');console.log(dtJa.format(date));// "2026/4/28"主要选项(options)
constoptions={dateStyle:'full',// 'full' | 'long' | 'medium' | 'short'timeStyle:'medium',// 同上weekday:'long',// 'narrow' | 'short' | 'long'year:'numeric',// '2-digit' | 'numeric'month:'long',// 'numeric' | '2-digit' | 'short' | 'long'day:'numeric',hour:'2-digit',minute:'2-digit',second:'2-digit',hour12:true,// 是否使用12小时制timeZone:'Asia/Shanghai',};constformatter=newIntl.DateTimeFormat('zh-CN',options);console.log(formatter.format(date));// 输出示例:"2026年4月28日星期二 下午03:30:00"formatToParts– 获取格式化后的各段内容
constparts=dtZh.formatToParts(date);// [{type:'year', value:'2026'}, {type:'month', value:'4'}, ...]使用Intl.DateTimeFormat快速格式化内置方法
也可以直接使用date.toLocaleString(),它在内部调用了Intl.DateTimeFormat:
console.log(date.toLocaleString('zh-CN',{dateStyle:'long'}));// "2026年4月28日"三、Intl.NumberFormat– 数字、货币、百分比
基础用法
constnum=1234567.89;newIntl.NumberFormat('en-US').format(num);// "1,234,567.89"newIntl.NumberFormat('de-DE').format(num);// "1.234.567,89"newIntl.NumberFormat('zh-CN').format(num);// "1,234,567.89"主要选项
constoptions={style:'currency',// 'decimal'(默认) | 'currency' | 'percent' | 'unit'currency:'CNY',// ISO 货币代码,如 'USD', 'EUR', 'JPY', 'CNY'currencyDisplay:'symbol',// 'symbol' | 'code' | 'name'minimumFractionDigits:2,maximumFractionDigits:2,useGrouping:true,// 是否使用千位分隔符notation:'compact',// 'standard' | 'scientific' | 'engineering' | 'compact'compactDisplay:'short',// 'short' (1.2万) | 'long' (1.2万)};示例
// 货币console.log(newIntl.NumberFormat('zh-CN',{style:'currency',currency:'USD'}).format(1234.5));// "US$1,234.50"// 百分比console.log(newIntl.NumberFormat('zh-CN',{style:'percent'}).format(0.1234));// "12%"// 紧凑显示(单位后缀)console.log(newIntl.NumberFormat('zh-CN',{notation:'compact'}).format(12500));// "1.25万"四、Intl.RelativeTimeFormat– 相对时间
基础用法
constrtf=newIntl.RelativeTimeFormat('zh-CN',{numeric:'auto'});console.log(rtf.format(-1,'day'));// "昨天"console.log(rtf.format(3,'day'));// "3天后"console.log(rtf.format(10,'minute'));// "10分钟后"可用的时间单位
'year','quarter','month','week','day','hour','minute','second'。
选项
numeric:'always'(总是用数字,如“1天前”)或'auto'(可能用“昨天”、“明天”)。style:'long'(“3 days ago”)、'short'(“3 days ago” 较短)、'narrow'。
实际应用:计算距今天数
functiontimeAgo(date){constrtf=newIntl.RelativeTimeFormat('zh-CN',{numeric:'auto'});constdiffDays=Math.round((date-newDate())/(1000*60*60*24));returnrtf.format(diffDays,'day');}console.log(timeAgo(newDate('2026-04-26')));// 2天前(取决于今天日期)五、Intl.ListFormat– 列表连接
基础用法
constlist=['苹果','香蕉','橘子'];constlf=newIntl.ListFormat('zh-CN',{style:'long',type:'conjunction'});console.log(lf.format(list));// "苹果、香蕉和橘子"选项
style:'long'(“A, B, and C”)、'short'、'narrow'(通常无逗号)。type:'conjunction'(“和”)、'disjunction'(“或”)、'unit'(“米/秒”风格)。
六、Intl.PluralRules– 单复数判定
主要用于根据数字选择正确词形(如英语中的 1 book / 2 books)。中文场景相对简单,但对某些语言必须。
constpr=newIntl.PluralRules('en-US');console.log(pr.select(1));// "one"console.log(pr.select(2));// "other"七、Intl.Collator– 语言敏感的字符串比较(排序)
constnames=['张三','李四','王五','陈六'];constcollator=newIntl.Collator('zh-CN',{sensitivity:'base'});names.sort(collator.compare);console.log(names);// 按拼音排序八、关键知识点与注意事项
1. 地区标识符(locale)
- 标准格式:
语言-国家/地区(如zh-CN、en-GB、zh-TW)。 - 可以使用
-u-扩展指定更多细则,如zh-CN-u-ca-chinese(使用农历)。
2. 性能影响
- 通常每次构造
Intl对象有一定开销。如果频繁使用,应将构造好的实例缓存起来复用。
3. 浏览器兼容性
- 主流现代浏览器和 Node.js 均完美支持。老旧浏览器(如 IE11)不支持,但如今基本可忽略。
4. 与Date.prototype.toLocaleString/Number.prototype.toLocaleString的关系
- 这些原型方法是
IntlAPI 的简易封装。两者选其一均可,但Intl构造函数更清晰地隔离配置,且在需要多次调用同一格式时性能更好(复用实例)。
九、实际项目组合示例
// 格式化当前时间 + 金额总计constnow=newDate();constprice=12345.6;constdateFormatter=newIntl.DateTimeFormat('zh-CN',{dateStyle:'full',timeStyle:'medium'});constmoneyFormatter=newIntl.NumberFormat('zh-CN',{style:'currency',currency:'CNY'});console.log(`订单时间:${dateFormatter.format(now)}`);console.log(`总金额:${moneyFormatter.format(price)}`);// 输出示例:// 订单时间:2026年4月28日星期二 下午03:30:00// 总金额:¥12,345.60总结
Intl对象是 JavaScript 原生国际化方案的基石,它:
- 消除了手工拼接数字、日期的繁琐。
- 自动处理不同地区文化习惯(尽管中文和英文习惯差异不大,但对德、法、阿拉伯语等差异很大)。
- 无需引入 moment.js / numeral.js 等库,性能更好,体积更小。
在你的日常开发中,如果需要跨地区展示或严格遵循本地化格式,应优先使用IntlAPI。对于简单的不涉及本地化的场景(如仅拼接字符串),模板字符串仍然是最轻量的选择。
如果还有关于某个具体构造函数或选项的疑问,欢迎继续提问!