实现JS深拷贝时出现的一个问题?

发布于 2022-09-12 02:53:35 字数 1038 浏览 24 评论 0

function extendDeep() {
  let deep = false, args = Array.from(arguments)

  if (typeof arguments[0] === "boolean") {
      deep = args.shift()
  }
  
  target = args.shift()

  args.forEach(item => {
      for (let i in item) {

          if (typeof item[i] === "object" && deep) {
              // 这里出了问题 ↓ 明明把递归后组合的对象赋值给了target["b"],却导致target自身被覆盖了
              console.log("递归之前:", target, i)
              target[i] = extendDeep(deep, target[i], item[i])
              console.log("递归之后:", target)
          } else {
              target[i] = item[i]
          }
      }
  })

  return target
}



// -----------------------------------------------


var obj1 = {
  a: 1,
  b: { b1: 1, b2: 2 }
};

var obj2 = {
  b: { b1: 3, b3: 4 },
  c: 3
};

var obj3 = {
  d: 4
}

console.log("最终结果:", extendDeep(true, obj1, obj2, obj3));

result.png

期望的结果是第二个打印为 递归之后:{a:1, b:{b1:3, b2:2, b3: 4}}

底子比较薄弱,第一次碰到这种问题,完全没有头绪哪里出错了,望大佬提点o(╥﹏╥)o

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

離殇 2022-09-19 02:53:35

函数内声明一下target,不然变成全局变量共用了。

  let deep = false, args = Array.from(arguments), target;
淡淡绿茶香 2022-09-19 02:53:35

方法传参要注意对象和数组都是地址传参,你的传参都是原始对象传进去,自然改变了改变原来对象的值。你可以修改传参方式如:

target[i] = extendDeep(deep, {...target[i]}, item[i])

在需要的地方用析构重新创建一个对象进去,就不会修改外面的对象了。

另外这种深拷贝可以使用插件去完成,不需要自己再去造轮子。如果是自己学习,那另当别论了。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文