JSON.parse(JSON.stringify(obj)) 无法深拷贝 Date 对象,因其序列化时转为 ISO 字符串并丢失类型;可用 reviver 函数手动还原、structuredClone(现代浏览器)或 lodash.cloneDeep(兼容旧环境)。

JavaScript 中使用 JSON.parse(JSON.stringify(obj)) 做深拷贝时,Date 对象会被转成字符串(ISO 格式),且拷贝后不再是 Date 实例,而是普通字符串 —— 这会导致后续调用 .getTime()、.getFullYear() 等方法时报错。
为什么 JSON 序列化会丢失 Date 类型
因为 JSON 标准不支持 Date 类型。当 JSON.stringify() 遇到 Date 实例时,会自动调用其 toISOString() 方法,输出类似 "2024-05-20T08:30:00.000Z" 的字符串,原始类型信息完全丢失。
手动还原 Date 对象的两种常用方式
在反序列化(JSON.parse)阶段,通过 reviver 函数识别日期字符串并重建 Date 实例:
- 判断字符串是否符合 ISO 8601 日期格式(如含
T和Z或+/-时区) - 尝试用该字符串构造新
Date,再验证是否有效(!isNaN(date.getTime())) - 只对「原本就是 Date」的字段还原,避免误转普通时间字符串(如
"2024-05-20")
示例代码:
立即学习“Java免费学习笔记(深入)”;
DMap GL地图JSAPI(dmapgl)开发指南。用于编写、审查、调试 DMap 地图 API 代码,涵盖地图初始化、覆盖物渲染、图层管理、事件处理、控件交互等任务。当用户提及 dmap、dmapgl、jsapi‑gl 或相关地图开发需求时自动触发。
const original = {
name: "Alice",
created: new Date("2024-05-20T10:30:00Z"),
meta: { updated: new Date("2024-05-21") }
};
const jsonStr = JSON.stringify(original);
const copy = JSON.parse(jsonStr, (key, value) => {
// 粗略匹配 ISO 日期字符串(可按需加强校验)
if (typeof value === 'string' && /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/.test(value)) {
const date = new Date(value);
if (!isNaN(date.getTime())) return date;
}
return value;
});
// copy.created instanceof Date → true
更健壮的方案:用 structuredClone(现代浏览器推荐)
structuredClone() 是原生支持 Date、Map、Set、RegExp 等类型的深拷贝 API,无需手动处理,也不依赖 JSON 中间格式:
- 兼容性:Chrome 98+、Firefox 94+、Edge 98+、Safari 16.4+
- 直接拷贝,保留所有内置对象类型和原型链关系(
Date拷贝后仍是Date实例) - 不支持函数、undefined、BigInt(和 JSON 一样),但对日期场景足够安全
用法简单:
const copy = structuredClone(original); // copy.created instanceof Date → true,且时间值完全一致
需要兼容老环境?选成熟的工具库
如果必须支持 IE 或旧版浏览器,推荐使用 lodash.cloneDeep():
- 自动识别并深拷贝
Date、RegExp、Error等特殊对象 - 内部已处理类型映射逻辑,开箱即用
- 注意:它不会把
Date转成字符串,也不会丢失精度
示例:
import { cloneDeep } from 'lodash-es';
const copy = cloneDeep(original); // Date 完整保留
不复杂但容易忽略 —— 关键是别默认信任 JSON.stringify 能保类型,尤其在涉及时间计算、比较或格式化前,务必确认拷贝后的对象仍是 Date 实例。

















