2025年3月7日大约 8 分钟
我将为您完善 Intl 对象的文档,详细介绍其功能和用法。
---
title: Intl对象
icon: javascript
order: 1
---
# Intl对象
Intl对象是ECMAScript国际化API的命名空间,提供了语言敏感的字符串比较、数字格式化和日期时间格式化功能。本文将介绍Intl对象的基本概念和通用用法。
## Intl 对象概述
`Intl` 对象是 ECMAScript 国际化 API 的核心,它提供了一系列构造函数和方法,用于处理不同语言和地区的格式化需求。这些功能使开发者能够创建适应全球用户的应用程序,而无需编写复杂的本地化逻辑。
`Intl` 对象不是构造函数,而是一个包含各种国际化构造函数和语言敏感函数的命名空间。
## 区域设置标识符
在使用 `Intl` 对象时,需要指定区域设置(locale)标识符,它通常由以下部分组成:
- 语言代码(必需):如 `en`(英语)、`zh`(中文)、`ja`(日语)
- 地区代码(可选):如 `US`(美国)、`CN`(中国)、`JP`(日本)
- 脚本代码(可选):如 `Hans`(简体中文)、`Hant`(繁体中文)
- 其他扩展(可选):如 `u-ca-buddhist`(使用佛教日历)
示例:
- `en-US`:美国英语
- `zh-CN`:中国大陆中文
- `zh-Hans-CN`:中国大陆简体中文
- `zh-Hant-TW`:台湾繁体中文
- `ja-JP`:日本日语
## Intl 构造函数
### Intl.Collator
`Intl.Collator` 用于语言敏感的字符串比较。
```javascript
// 创建一个中文排序器
const collator = new Intl.Collator('zh-CN');
// 比较两个字符串
console.log(collator.compare('你好', '世界')); // 返回一个数字表示排序顺序
// 对数组进行排序
const fruits = ['苹果', '香蕉', '橙子', '梨'];
fruits.sort(collator.compare);
console.log(fruits); // 按照中文排序规则排序
配置选项
const collator = new Intl.Collator('zh-CN', {
sensitivity: 'base', // 'base', 'accent', 'case', 或 'variant'
ignorePunctuation: true, // 是否忽略标点符号
numeric: true, // 是否使用数字排序
caseFirst: 'false' // 'upper', 'lower', 或 'false'
});
Intl.DateTimeFormat
Intl.DateTimeFormat
用于语言敏感的日期和时间格式化。
// 创建一个中文日期格式化器
const dateFormatter = new Intl.DateTimeFormat('zh-CN');
// 格式化当前日期
console.log(dateFormatter.format(new Date())); // 例如:2023/4/1
// 使用更多选项
const options = {
year: 'numeric',
month: 'long',
day: 'numeric',
weekday: 'long',
hour: 'numeric',
minute: 'numeric',
second: 'numeric',
timeZone: 'Asia/Shanghai',
hour12: true
};
const detailedFormatter = new Intl.DateTimeFormat('zh-CN', options);
console.log(detailedFormatter.format(new Date())); // 例如:2023年4月1日星期六 上午8:30:45
配置选项
const options = {
dateStyle: 'full', // 'full', 'long', 'medium', 或 'short'
timeStyle: 'medium', // 'full', 'long', 'medium', 或 'short'
calendar: 'chinese', // 日历系统,如 'gregory', 'chinese', 'japanese'
dayPeriod: 'long', // 'narrow', 'short', 或 'long'
numberingSystem: 'latn', // 数字系统,如 'latn', 'arab', 'hans'
timeZone: 'Asia/Shanghai', // 时区
hour12: false, // 是否使用12小时制
formatMatcher: 'best fit' // 'basic' 或 'best fit'
};
Intl.NumberFormat
Intl.NumberFormat
用于语言敏感的数字格式化。
// 创建一个中文数字格式化器
const numberFormatter = new Intl.NumberFormat('zh-CN');
// 格式化数字
console.log(numberFormatter.format(123456.789)); // 123,456.789
// 货币格式化
const currencyFormatter = new Intl.NumberFormat('zh-CN', {
style: 'currency',
currency: 'CNY'
});
console.log(currencyFormatter.format(123456.789)); // ¥123,456.79
// 百分比格式化
const percentFormatter = new Intl.NumberFormat('zh-CN', {
style: 'percent'
});
console.log(percentFormatter.format(0.1234)); // 12.34%
配置选项
const options = {
style: 'decimal', // 'decimal', 'currency', 'percent', 或 'unit'
currency: 'EUR', // 当 style 为 'currency' 时使用的货币代码
currencyDisplay: 'symbol', // 'symbol', 'code', 或 'name'
useGrouping: true, // 是否使用千位分隔符
minimumIntegerDigits: 1, // 最小整数位数
minimumFractionDigits: 0, // 最小小数位数
maximumFractionDigits: 3, // 最大小数位数
minimumSignificantDigits: 1, // 最小有效数字位数
maximumSignificantDigits: 21, // 最大有效数字位数
notation: 'standard', // 'standard', 'scientific', 'engineering', 或 'compact'
compactDisplay: 'short', // 'short' 或 'long',当 notation 为 'compact' 时使用
unit: 'kilometer', // 当 style 为 'unit' 时使用的单位
unitDisplay: 'long' // 'narrow', 'short', 或 'long'
};
Intl.PluralRules
Intl.PluralRules
用于确定不同语言中的复数形式。
// 创建一个英语复数规则
const pluralRules = new Intl.PluralRules('en-US');
// 获取数字的复数类别
console.log(pluralRules.select(0)); // 'other'
console.log(pluralRules.select(1)); // 'one'
console.log(pluralRules.select(2)); // 'other'
// 实际应用:根据数量选择正确的文本
function getItemText(count) {
const category = pluralRules.select(count);
const texts = {
one: '1 item',
other: `${count} items`
};
return texts[category];
}
console.log(getItemText(1)); // '1 item'
console.log(getItemText(2)); // '2 items'
Intl.RelativeTimeFormat
Intl.RelativeTimeFormat
用于格式化相对时间,如"3天前"、"2小时后"等。
// 创建一个中文相对时间格式化器
const rtf = new Intl.RelativeTimeFormat('zh-CN', { style: 'long' });
// 格式化相对时间
console.log(rtf.format(-1, 'day')); // 1天前
console.log(rtf.format(2, 'day')); // 2天后
console.log(rtf.format(-1, 'year')); // 1年前
console.log(rtf.format(3, 'month')); // 3个月后
console.log(rtf.format(-5, 'minute')); // 5分钟前
配置选项
const options = {
localeMatcher: 'best fit', // 'lookup' 或 'best fit'
numeric: 'always', // 'always' 或 'auto'
style: 'long' // 'long', 'short', 或 'narrow'
};
Intl.ListFormat
Intl.ListFormat
用于格式化列表,如"A、B和C"。
// 创建一个中文列表格式化器
const listFormat = new Intl.ListFormat('zh-CN', { style: 'long', type: 'conjunction' });
// 格式化列表
const fruits = ['苹果', '香蕉', '橙子'];
console.log(listFormat.format(fruits)); // 苹果、香蕉和橙子
// 不同类型的列表
const disjunctionFormat = new Intl.ListFormat('zh-CN', { type: 'disjunction' });
console.log(disjunctionFormat.format(fruits)); // 苹果、香蕉或橙子
配置选项
const options = {
localeMatcher: 'best fit', // 'lookup' 或 'best fit'
style: 'long', // 'long', 'short', 或 'narrow'
type: 'conjunction' // 'conjunction', 'disjunction', 或 'unit'
};
Intl.Segmenter
Intl.Segmenter
用于文本分段,如分词、分句等。
// 创建一个中文分词器
const segmenter = new Intl.Segmenter('zh-CN', { granularity: 'word' });
// 分词
const text = '你好,世界!';
const segments = segmenter.segment(text);
// 遍历分词结果
for (const segment of segments) {
console.log(`${segment.segment} [${segment.index}:${segment.index + segment.segment.length}]`);
}
// 创建一个分句器
const sentenceSegmenter = new Intl.Segmenter('zh-CN', { granularity: 'sentence' });
const sentences = sentenceSegmenter.segment('你好!我是小明。今天天气真好!');
// 遍历分句结果
for (const sentence of sentences) {
console.log(sentence.segment);
}
配置选项
const options = {
granularity: 'word', // 'grapheme', 'word', 或 'sentence'
};
实用方法
Intl.getCanonicalLocales()
获取规范化的区域设置标识符。
console.log(Intl.getCanonicalLocales(['zh-cn', 'en-us'])); // ['zh-CN', 'en-US']
Intl.supportedValuesOf()
获取特定类别的支持值。
// 获取支持的时区
console.log(Intl.supportedValuesOf('timeZone'));
// ['Africa/Abidjan', 'Africa/Accra', ...]
// 获取支持的日历
console.log(Intl.supportedValuesOf('calendar'));
// ['buddhist', 'chinese', 'coptic', 'gregory', ...]
// 获取支持的货币
console.log(Intl.supportedValuesOf('currency'));
// ['ADP', 'AED', 'AFA', 'AFN', ...]
实际应用示例
多语言日期格式化
function formatDateForLocale(date, locale) {
const formatter = new Intl.DateTimeFormat(locale, {
year: 'numeric',
month: 'long',
day: 'numeric',
weekday: 'long'
});
return formatter.format(date);
}
const today = new Date();
console.log(formatDateForLocale(today, 'zh-CN')); // 2023年4月1日星期六
console.log(formatDateForLocale(today, 'en-US')); // Saturday, April 1, 2023
console.log(formatDateForLocale(today, 'ja-JP')); // 2023年4月1日土曜日
console.log(formatDateForLocale(today, 'de-DE')); // Samstag, 1. April 2023
货币转换显示
function formatCurrency(amount, currency, locale) {
return new Intl.NumberFormat(locale, {
style: 'currency',
currency: currency
}).format(amount);
}
const price = 123456.789;
console.log(formatCurrency(price, 'CNY', 'zh-CN')); // ¥123,456.79
console.log(formatCurrency(price, 'USD', 'en-US')); // $123,456.79
console.log(formatCurrency(price, 'EUR', 'de-DE')); // 123.456,79 €
console.log(formatCurrency(price, 'JPY', 'ja-JP')); // ¥123,457
多语言排序
function sortNamesForLocale(names, locale) {
const collator = new Intl.Collator(locale);
return [...names].sort(collator.compare);
}
const names = ['张三', '李四', '王五', '赵六'];
console.log(sortNamesForLocale(names, 'zh-CN')); // 按中文排序
console.log(sortNamesForLocale(names, 'en-US')); // 按英文排序
相对时间显示
function formatRelativeTime(date, locale) {
const rtf = new Intl.RelativeTimeFormat(locale, { numeric: 'auto' });
const now = new Date();
const diffInSeconds = Math.floor((date - now) / 1000);
if (Math.abs(diffInSeconds) < 60) {
return rtf.format(Math.floor(diffInSeconds), 'second');
} else if (Math.abs(diffInSeconds) < 3600) {
return rtf.format(Math.floor(diffInSeconds / 60), 'minute');
} else if (Math.abs(diffInSeconds) < 86400) {
return rtf.format(Math.floor(diffInSeconds / 3600), 'hour');
} else if (Math.abs(diffInSeconds) < 2592000) {
return rtf.format(Math.floor(diffInSeconds / 86400), 'day');
} else if (Math.abs(diffInSeconds) < 31536000) {
return rtf.format(Math.floor(diffInSeconds / 2592000), 'month');
} else {
return rtf.format(Math.floor(diffInSeconds / 31536000), 'year');
}
}
// 使用示例
const pastDate = new Date();
pastDate.setDate(pastDate.getDate() - 3);
console.log(formatRelativeTime(pastDate, 'zh-CN')); // 3天前
const futureDate = new Date();
futureDate.setHours(futureDate.getHours() + 5);
console.log(formatRelativeTime(futureDate, 'zh-CN')); // 5小时后
多语言数字单位格式化
function formatNumberWithUnit(number, unit, locale) {
return new Intl.NumberFormat(locale, {
style: 'unit',
unit: unit,
unitDisplay: 'long'
}).format(number);
}
console.log(formatNumberWithUnit(100, 'meter', 'zh-CN')); // 100米
console.log(formatNumberWithUnit(100, 'meter', 'en-US')); // 100 meters
console.log(formatNumberWithUnit(2.5, 'liter', 'zh-CN')); // 2.5升
console.log(formatNumberWithUnit(2.5, 'liter', 'en-US')); // 2.5 liters
多语言列表格式化
function formatList(items, locale, type = 'conjunction') {
const listFormat = new Intl.ListFormat(locale, { style: 'long', type: type });
return listFormat.format(items);
}
const ingredients = ['面粉', '鸡蛋', '牛奶', '糖'];
console.log(formatList(ingredients, 'zh-CN')); // 面粉、鸡蛋、牛奶和糖
console.log(formatList(ingredients, 'en-US')); // 面粉, 鸡蛋, 牛奶, and 糖
console.log(formatList(ingredients, 'zh-CN', 'disjunction')); // 面粉、鸡蛋、牛奶或糖
浏览器兼容性
Intl
对象及其构造函数在现代浏览器中得到了广泛支持,但不同的浏览器和版本对特定功能的支持可能有所不同。
Intl.Collator
、Intl.DateTimeFormat
和Intl.NumberFormat
在所有现代浏览器中都有良好支持Intl.PluralRules
和Intl.RelativeTimeFormat
在较新的浏览器版本中支持Intl.ListFormat
和Intl.Segmenter
是较新的添加,可能需要检查兼容性
在使用较新的 Intl
功能时,建议检查目标浏览器的兼容性,并考虑使用 polyfill 来增强兼容性。
性能考虑
创建 Intl
对象的实例可能是一个相对昂贵的操作,特别是在需要处理大量数据时。为了优化性能,可以考虑以下策略:
- 重用实例:创建一次
Intl
对象实例,然后多次使用它
// 低效方式
function formatMany(numbers) {
return numbers.map(n => new Intl.NumberFormat('zh-CN').format(n));
}
// 高效方式
function formatManyEfficient(numbers) {
const formatter = new Intl.NumberFormat('zh-CN');
return numbers.map(n => formatter.format(n));
}
- 批量处理:使用
formatToParts
或formatRange
等方法一次处理多个值
// 获取格式化的各个部分
const parts = new Intl.DateTimeFormat('zh-CN', {
year: 'numeric',
month: 'long',
day: 'numeric'
}).formatToParts(new Date());
console.log(parts);
// [
// { type: 'year', value: '2023' },
// { type: 'literal', value: '年' },
// { type: 'month', value: '4' },
// { type: 'literal', value: '月' },
// { type: 'day', value: '1' },
// { type: 'literal', value: '日' }
// ]
总结
Intl
对象是 JavaScript 中处理国际化的强大工具,它提供了一系列构造函数和方法,用于处理不同语言和地区的格式化需求。通过使用 Intl
对象,开发者可以轻松实现多语言支持,而无需编写复杂的本地化逻辑。
主要优点包括:
- 标准化:使用 ECMAScript 标准 API,确保跨浏览器一致性
- 性能:比自定义实现更高效,因为它通常使用浏览器的原生实现
- 准确性:基于 Unicode CLDR(通用语言环境数据存储库)数据,提供准确的本地化规则
- 灵活性:提供丰富的选项来自定义格式化行为
通过掌握 Intl
对象,开发者可以创建真正国际化的应用程序,为全球用户提供本地化的体验。随着 Web 应用程序的全球化,Intl
对象将成为前端开发者工具箱中越来越重要的工具。