You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript中含嵌套对象数组的深拷贝方案(保留Date属性)

嘿,我完全懂你的困扰!JSON.parse(JSON.stringify())确实是很多人第一时间想到的深拷贝方法,但碰到Date这种特殊类型就直接歇菜了——它会把Date对象转成ISO字符串,根本不是原来的Date实例。针对你这种包含嵌套对象数组的结构,我给你几个实用的TypeScript解决方案:

解决方案1:手动实现递归深拷贝(自定义控制类型处理)

如果你不想依赖任何第三方库,自己写一个递归深拷贝函数是最灵活的,还能精准处理Date类型:

function deepClone<T>(obj: T): T {
  // 处理null和基本数据类型(直接返回)
  if (obj === null || typeof obj !== 'object') {
    return obj;
  }

  // 单独处理Date对象:创建新的Date实例保留时间
  if (obj instanceof Date) {
    return new Date(obj.getTime()) as T;
  }

  // 处理数组(包括嵌套数组:遍历每个元素递归拷贝)
  if (Array.isArray(obj)) {
    return obj.map(item => deepClone(item)) as T;
  }

  // 处理普通对象(包括带嵌套数组的对象:遍历键值对递归拷贝)
  const clonedObj = {} as Record<string, any>;
  for (const key in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, key)) {
      clonedObj[key] = deepClone(obj[key]);
    }
  }
  return clonedObj as T;
}

// 用法示例
const originalArray = [
  { id: 1, name: "Item 1", createdAt: new Date(), nested: [{ id: 11 }, { id: 12 }] },
  { id: 2, name: "Item 2", createdAt: new Date(), nested: [{ id: 21 }] }
];

const clonedArray = deepClone(originalArray);
// 验证:克隆后的Date是新实例,但时间一致
console.log(clonedArray[0].createdAt instanceof Date); // true
console.log(clonedArray[0].createdAt.getTime() === originalArray[0].createdAt.getTime()); // true
// 嵌套数组也被正确克隆
console.log(clonedArray[0].nested !== originalArray[0].nested); // true

这个函数会逐个检查每个值的类型:碰到Date就新建一个Date实例,数组就遍历每个元素递归拷贝,普通对象则遍历所有自有属性递归处理,完美适配你的嵌套数组结构。

解决方案2:使用原生structuredClone API(简洁高效)

如果你项目的运行环境支持现代浏览器(Chrome 98+、Firefox 94+)或Node.js 17+,原生的structuredClone API是最省心的选择——它内置支持深拷贝,还能正确处理Date、Map、Set等特殊类型,包括嵌套数组:

const clonedArray = structuredClone(originalArray);

// 验证
console.log(clonedArray[0].createdAt instanceof Date); // true
console.log(clonedArray[0].nested !== originalArray[0].nested); // true

这个方法不需要自己写任何递归逻辑,一行代码搞定,唯一要注意的是兼容性:如果需要支持旧浏览器或低版本Node.js,可能就不太适用了。

解决方案3:用lodash的cloneDeep(成熟省心)

如果你的项目已经在使用lodash,直接用它的cloneDeep方法就好——这是一个经过大量场景验证的深拷贝工具,能处理各种 edge case(比如循环引用),而且TypeScript类型支持非常完善:

首先安装依赖(如果还没装):

npm install lodash @types/lodash

然后使用:

import cloneDeep from 'lodash/cloneDeep';

const clonedArray = cloneDeep(originalArray);

// 验证
console.log(clonedArray[0].createdAt instanceof Date); // true
console.log(clonedArray[0].nested !== originalArray[0].nested); // true

这个方法的优势是不用自己维护深拷贝逻辑,lodash已经帮你处理了所有特殊情况,适合追求稳定性的项目。

总结
  • 想自定义控制类型处理、不依赖第三方库:选手动递归深拷贝
  • 环境支持现代API、追求简洁:选structuredClone
  • 项目已有lodash、追求稳定性:选lodash.cloneDeep

内容的提问来源于stack exchange,提问作者Paul Clavier

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:50:10