Internationalized API
Core Features of ECMAScript 6 Internationalization API
ECMAScript 6 introduced the Intl
object as the core entry point for internationalization APIs, providing language-sensitive string comparison, number formatting, and date-time formatting capabilities. These APIs do not rely on third-party libraries but are built directly into the JavaScript engine, supported natively by browsers or Node.js. The Intl
object includes three constructors: Collator
, NumberFormat
, and DateTimeFormat
, each addressing different internationalization needs.
// Check if the environment supports the Intl API
if (typeof Intl === 'object' && Intl !== null) {
console.log('Current environment supports internationalization APIs');
}
Localized String Comparison
The Intl.Collator
object provides language-sensitive string comparison, overcoming the limitations of the traditional localeCompare
method. By specifying locale
and options
parameters, sorting based on specific language rules can be achieved.
const names = ['王伟', '李娜', '张伟', '刘洋'];
const collator = new Intl.Collator('zh-CN');
names.sort(collator.compare);
console.log(names); // Outputs results following Chinese sorting rules
Configuration options support various comparison methods:
sensitivity: 'base'
ignores case and accent differencesnumeric: true
enables natural sorting of numberscaseFirst: 'upper'
sorts uppercase letters first
const files = ['file1', 'file10', 'file2'];
const numericSorter = new Intl.Collator(undefined, { numeric: true });
files.sort(numericSorter.compare);
console.log(files); // ['file1', 'file2', 'file10']
Number Formatting
Intl.NumberFormat
enables localized display of numbers, including currency, percentages, and units. The constructor accepts locales
parameters and a configuration object, supporting over 200 regional settings.
const price = 123456.789;
console.log(new Intl.NumberFormat('de-DE').format(price)); // "123.456,789"
console.log(new Intl.NumberFormat('ja-JP').format(price)); // "123,456.789"
Currency formatting example:
const formatter = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
minimumFractionDigits: 2
});
console.log(formatter.format(1000)); // "$1,000.00"
Advanced configuration options include:
notation: 'compact'
enables compact formatting (e.g., 1.2K)unitDisplay: 'long'
shows full unit namessignDisplay: 'always'
always displays positive/negative signs
const shortFormat = new Intl.NumberFormat('en', {
notation: 'compact',
compactDisplay: 'short'
});
console.log(shortFormat.format(1500)); // "1.5K"
Date and Time Localization
Intl.DateTimeFormat
provides powerful date and time formatting capabilities, automatically adapting to regional date representation conventions. Basic usage only requires specifying the locale parameter to obtain date formats that conform to local customs.
const date = new Date();
console.log(new Intl.DateTimeFormat('en-US').format(date)); // "5/15/2023"
console.log(new Intl.DateTimeFormat('zh-CN').format(date)); // "2023/5/15"
Precise output formatting can be controlled via the options parameter:
const opts = {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric',
hour: '2-digit',
minute: '2-digit',
timeZoneName: 'short'
};
const formatter = new Intl.DateTimeFormat('zh-TW', opts);
console.log(formatter.format(new Date())); // "2023年5月15日 星期一 14:30 CST"
Time zone handling is particularly powerful:
const nyTime = new Intl.DateTimeFormat('en-US', {
timeZone: 'America/New_York',
hour: 'numeric',
minute: 'numeric'
}).format(new Date());
console.log(`Current time in New York: ${nyTime}`);
Relative Time Formatting
The ECMAScript Internationalization API extends relative time formatting capabilities. Using Intl.RelativeTimeFormat
, descriptions like "yesterday" or "2 months ago" can be generated.
const rtf = new Intl.RelativeTimeFormat('zh', {
numeric: 'auto'
});
console.log(rtf.format(-1, 'day')); // "昨天"
console.log(rtf.format(2, 'month')); // "2个月后"
Supported time units include:
second
minute
hour
day
week
month
quarter
(partial implementations)year
function getRelativeTime(timestamp) {
const now = Date.now();
const diff = timestamp - now;
const units = [
{ unit: 'second', ms: 1000 },
{ unit: 'minute', ms: 60000 },
// Other units...
];
for (const { unit, ms } of units) {
if (Math.abs(diff) >= ms) {
return rtf.format(Math.round(diff/ms), unit);
}
}
return 'Just now';
}
List Formatting
Intl.ListFormat
converts arrays into linguistically appropriate list representations, automatically handling conjunctions and separators.
const list = ['苹果', '香蕉', '橙子'];
const lf = new Intl.ListFormat('zh');
console.log(lf.format(list)); // "苹果、香蕉和橙子"
const lfEn = new Intl.ListFormat('en');
console.log(lfEn.format(list)); // "apples, bananas, and oranges"
Configuration options include:
style: 'long'
uses full conjunctions ("and")type: 'disjunction'
uses "or" for connections
const orList = new Intl.ListFormat('zh', {
type: 'disjunction'
});
console.log(orList.format(['微信', '支付宝', '现金']));
// "微信、支付宝或现金"
Multilingual Processing in Practice
Real-world projects often require dynamic language switching, which can be implemented as follows:
class I18nService {
constructor(locale = navigator.language) {
this.locale = locale;
this.messages = {
'en-US': { welcome: 'Welcome' },
'zh-CN': { welcome: '欢迎' }
};
}
t(key) {
return this.messages[this.locale]?.[key] || key;
}
formatNumber(value, options) {
return new Intl.NumberFormat(this.locale, options).format(value);
}
// Other formatting methods...
}
const i18n = new I18nService('zh-CN');
console.log(i18n.t('welcome')); // "欢迎"
Performance Optimization Considerations
Frequently creating formatter instances can impact performance. For repeated usage scenarios, instances should be cached:
const formatterCache = new Map();
function getFormatter(locale, options) {
const key = JSON.stringify({ locale, ...options });
if (!formatterCache.has(key)) {
formatterCache.set(key, new Intl.DateTimeFormat(locale, options));
}
return formatterCache.get(key);
}
For server-side rendering scenarios, ensure client and server locales match:
function getClientLocale(req) {
return req.headers['accept-language']?.split(',')[0] || 'en-US';
}
Browser Compatibility Strategy
While modern browsers generally support the Intl API, compatibility solutions are still needed:
function safeDateFormat(date, locale, options) {
try {
return new Intl.DateTimeFormat(locale, options).format(date);
} catch (e) {
// Fallback solution
return date.toLocaleDateString();
}
}
For environments requiring polyfills, libraries like intl
and intl-locales-supported
can be loaded:
if (!global.Intl) {
await import('intl');
await import('intl/locale-data/jsonp/en-US');
await import('intl/locale-data/jsonp/zh-CN');
}
Advanced Formatting Techniques
Combining multiple formatters can achieve complex effects:
function formatPriceWithSymbol(amount, currency, locale) {
const numFormat = new Intl.NumberFormat(locale, {
style: 'currency',
currency,
currencyDisplay: 'code'
});
const parts = numFormat.formatToParts(amount);
return parts.map(({ type, value }) =>
type === 'currency' ? getCurrencySymbol(currency) : value
).join('');
}
Handling plural forms in internationalized displays:
const pluralRules = new Intl.PluralRules('en-US');
console.log(pluralRules.select(1)); // "one"
console.log(pluralRules.select(5)); // "other"
function getPluralMessage(count) {
const rules = new Intl.PluralRules('en');
switch (rules.select(count)) {
case 'one': return `${count} item`;
default: return `${count} items`;
}
}
Unit Formatting
Intl.NumberFormat
's unit formatting capability handles various measurement units:
const speedFormatter = new Intl.NumberFormat('en', {
style: 'unit',
unit: 'kilometer-per-hour',
unitDisplay: 'short'
});
console.log(speedFormatter.format(100)); // "100 km/h"
const tempFormatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'celsius',
unitDisplay: 'narrow'
});
console.log(tempFormatter.format(25)); // "25°C"
Supported unit types include:
- Length:
meter
,inch
,foot
, etc. - Volume:
liter
,gallon
,pint
, etc. - Mass:
gram
,kilogram
,ounce
, etc. - Temperature:
celsius
,fahrenheit
- Speed:
kilometer-per-hour
,mile-per-hour
const weightFormatter = new Intl.NumberFormat('zh-CN', {
style: 'unit',
unit: 'kilogram',
unitDisplay: 'long'
});
console.log(weightFormatter.format(50)); // "50千克"
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn