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

如何在JavaScript中深度克隆数组并保留类型且避免引用关联?

解决JavaScript数组深度克隆并保留Date类型的问题

针对你包含Date对象和嵌套对象的数组const a = [1, new Date(), false, { date: new Date(), name: "John Doe" }],以下是两种可行的克隆方案:

方案一:使用原生structuredClone API

这是ES2022引入的原生深度克隆API,专门解决复杂类型的深拷贝问题,能直接保留Date、Map、Set等内置类型,且无需手动编写递归逻辑:

const a = [1, new Date(), false, { date: new Date(), name: "John Doe" }];
const clonedA = structuredClone(a);

// 验证克隆效果
clonedA[3].name = "Jane Doe";
clonedA[3].date.setFullYear(2025);
clonedA[1].setFullYear(2026);

console.log(a[3].name); // 输出 "John Doe"(原数组不受影响)
console.log(a[3].date.getFullYear()); // 输出原日期年份(不受修改影响)
console.log(a[1].getFullYear()); // 输出原日期年份(不受修改影响)

注意:structuredClone不支持克隆函数、Symbol值、循环引用对象(如果需要处理循环引用,可以在自定义函数中添加缓存),但对于你的场景完全适用。

方案二:自定义递归深度克隆函数

如果需要兼容不支持structuredClone的旧环境(如IE),或者需要自定义克隆逻辑,可以手动实现递归克隆:

function deepClone(obj) {
  // 处理基本类型、null和undefined
  if (obj === null || typeof obj !== 'object') return obj;

  // 单独处理Date类型
  if (obj instanceof Date) {
    return new Date(obj.getTime());
  }

  // 处理数组
  if (Array.isArray(obj)) {
    return obj.map(item => deepClone(item));
  }

  // 处理普通对象
  const clonedObj = {};
  for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
      clonedObj[key] = deepClone(obj[key]);
    }
  }
  return clonedObj;
}

// 使用示例
const a = [1, new Date(), false, { date: new Date(), name: "John Doe" }];
const clonedA = deepClone(a);

// 验证修改不影响原数组
clonedA[3].name = "Jane Doe";
console.log(a[3].name); // 输出 "John Doe"

如果需要处理循环引用,可以给函数添加一个缓存参数(如new WeakMap()),记录已克隆的对象,避免递归栈溢出。

总结

  • 现代环境优先使用structuredClone,简洁高效且原生支持类型保留;
  • 旧环境或需要自定义逻辑时,使用递归深度克隆函数。

内容的提问来源于stack exchange,提问作者Simon Trichereau

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 13:05:11