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

如何在不使用递归及现成方法的情况下实现对象深拷贝

如何实现不使用递归、JSON方法和structuredClone的完整深拷贝?

原代码存在的问题

你的deepCopy函数有两个核心问题导致无法完成完整深拷贝:

  1. 数组处理逻辑错误:直接将数组的第一个元素作为处理对象,完全忽略了数组本身的结构,无法正确拷贝数组类型的输入。
  2. 仅支持两层嵌套:只手动遍历了一层嵌套对象,更深层级的对象/数组会直接赋值引用,没有进行迭代拷贝,导致深层数据仍共享原对象的内存地址。

迭代式深拷贝实现(非递归)

我们可以用**栈(Stack)**来实现迭代式的深拷贝,遍历所有嵌套层级,同时处理对象、数组、基本类型,还能避免循环引用问题:

function deepCopy(source) {
  // 处理非对象/数组的情况:直接返回原值
  if (source === null || typeof source !== 'object') {
    return source;
  }

  // 初始化拷贝的根结构:数组或对象
  const target = Array.isArray(source) ? [] : {};
  // 用Map记录已拷贝的对象,避免循环引用导致死循环
  const copiedMap = new Map();
  copiedMap.set(source, target);

  // 栈结构:每个元素保存 [原数据节点, 目标数据节点]
  const stack = [[source, target]];

  while (stack.length > 0) {
    const [currentSource, currentTarget] = stack.pop();

    // 遍历当前节点的所有键(数组是索引,对象是属性名)
    const keys = Array.isArray(currentSource) 
      ? Array.from({ length: currentSource.length }, (_, i) => i) 
      : Object.keys(currentSource);
    
    for (const key of keys) {
      const value = currentSource[key];

      // 基本类型(包括null、undefined)直接赋值
      if (value === null || typeof value !== 'object') {
        currentTarget[key] = value;
        continue;
      }

      // 处理已拷贝过的对象(循环引用)
      if (copiedMap.has(value)) {
        currentTarget[key] = copiedMap.get(value);
        continue;
      }

      // 创建新的嵌套结构(数组或对象)
      const newTarget = Array.isArray(value) ? [] : {};
      copiedMap.set(value, newTarget);
      currentTarget[key] = newTarget;

      // 将新节点压入栈,继续处理深层嵌套
      stack.push([value, newTarget]);
    }
  }

  return target;
}

测试验证

用你提供的示例数据测试:

const data1 = {
  a: 10,
  y: null,
  k: [1, 2],
  b: 3,
  c: {
    d: 4,
    e: {
      w: 50,
      u: undefined,
      s: {
        f: {
          v: 5,
        },
      },
    },
  },
};

const data2 = [
  {
    a: 10,
    y: null,
    k: [1, 2],
    b: 3,
    c: {
      d: 4,
      e: {
        w: 50,
        u: undefined,
        s: {
          f: {
            v: 5,
          },
        },
      },
    },
  },
];

const copy1 = deepCopy(data1);
const copy2 = deepCopy(data2);

// 验证深层修改不影响原对象
copy1.c.e.s.f.v = 100;
console.log(data1.c.e.s.f.v); // 输出5,原对象未被修改
console.log(copy1.c.e.s.f.v); // 输出100,拷贝对象已修改

copy2[0].k[0] = 99;
console.log(data2[0].k[0]); // 输出1,原数组未被修改
console.log(copy2[0].k[0]); // 输出99,拷贝数组已修改

核心逻辑说明

  • 栈迭代:通过栈保存待处理的节点,替代递归的调用栈,实现对任意深度嵌套结构的遍历。
  • 类型区分:正确识别数组和对象类型,创建对应的空结构进行拷贝。
  • 循环引用处理:用Map记录已经拷贝过的对象,避免循环引用导致的死循环和重复拷贝。
  • 全类型覆盖:支持基本类型(number、string、boolean、null、undefined)、对象、数组的拷贝。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 08:13:21