复用 Intl.DateTimeFormat 实例是规避初始化开销最有效的方式。每次 new Intl.DateTimeFormat() 都会触发内部解析、区域数据加载和格式化逻辑编译,高频调用时性能损耗显著;应按 locale + options 组合唯一缓存实例,推荐用 Map 或 WeakMap 管理键名,避免内存泄漏与动态 options 混用。

直接复用 Intl.DateTimeFormat 实例是规避初始化开销最有效的方式。每次 new Intl.DateTimeFormat() 都会触发内部解析、区域数据加载和格式化逻辑编译,这个过程在高频调用(如渲染列表、导出万条日志)中会显著拖慢性能——测试显示,重复创建 2 万次比复用单个实例慢约 70 倍。
缓存核心原则:按 locale + options 组合唯一实例
Intl.DateTimeFormat 实例不可跨配置复用。相同语言环境(如 'zh-CN')但不同选项(如一个带时区,一个不带),必须创建不同实例。缓存的关键是把 locale 和 options 转为稳定键名:
- 将 options 对象 JSON.stringify 后作为缓存 key 的一部分(注意:需保证 options 属性顺序一致,建议用标准化函数或 Map 存储原始对象)
- 推荐使用 Map 或 WeakMap 管理,避免内存泄漏;若全局复用,可用普通对象或 Map,键格式如 'zh-CN|{"dateStyle":"medium","timeZone":"Asia/Shanghai"}'
- 不要缓存动态 options(如每次传入不同 timeZone),应提前预置常用时区格式器
实用缓存封装示例
以下是一个轻量、线程安全的缓存工具函数:
const formatterCache = new Map();
function getFormatter(locale, options = {}) {
const key = `${locale}|${JSON.stringify(options)}`;
if (!formatterCache.has(key)) {
formatterCache.set(key, new Intl.DateTimeFormat(locale, options));
}
return formatterCache.get(key);
}
// 使用
const cnShort = getFormatter('zh-CN', { dateStyle: 'short', timeStyle: 'short' });
const usLong = getFormatter('en-US', { dateStyle: 'long', timeZone: 'America/New_York' });
console.log(cnShort.format(new Date())); // "26/5/11 上午5:12"
console.log(usLong.format(new Date())); // "Monday, May 11, 2026 at 3:12:00 PM Eastern Daylight Time"
预定义常用格式,减少运行时判断
避免在循环中动态生成 options。把业务中高频使用的组合提前声明为常量:
- 例如:DATE_ONLY_CN、DATETIME_TOKYO、TIMESTAMP_UTC
- 这些常量对应已初始化好的 formatter 实例,直接 import 即可调用 .format()
- 既提升性能,也增强代码可读性与维护性,防止拼写错误或选项冲突
注意时区与 locale 的分离设计
时区(timeZone)属于格式化行为,不影响 locale 本身的语义。同一个 locale(如 'en-US')可搭配多个 timeZone 创建多个缓存实例,但不要混用——比如 'en-US' + 'UTC' 和 'en-US' + 'Europe/London' 必须是两个独立 formatter。IANA 时区名(如 'Asia/Shanghai')必须准确,禁用 PST/EST 等模糊缩写,否则缓存后仍可能返回错误时间。

















