Js 怎么深拷贝嵌套对象?

一个对象 o = { a: 1 }; o.b = o,深拷贝 o 的方法是什么?

阅读 2.5k
2 个回答

因为 o 对象中存在循环引用 o.b,导致无法进行 stringify,所以能用 JSON.parse(JSON.stringify(o)) 做深拷贝

可以考虑使用 lodash 的 _.cloneDeep(o) 函数,支持循环引用深拷贝,原理是使用键值对数组记录每个原对象到拷贝对象的映射,拷贝时递归每个属性,检查数组中是否已存在该属性的拷贝,有就直接取出,没有就创建该属性的拷贝并存储

另外可以使用 MapWeakMap 存储原对象到拷贝对象的映射,性能比数组更好

参考代码

// 支持循环引用深拷贝
const cloneCircular = (o, clones = new WeakMap()) => {
  if (!o || typeof o != 'object') return o
  if (clones.has(o)) return clones.get(o)
  const c = Array.isArray(o) ? [] : {}
  clones.set(o, c)
  Object.keys(o).forEach(k => c[k] = cloneCircular(o[k], clones))
  return c
}

const o1 = { a: 1 }
o1.b = o1

const o2 = cloneCircular(o1)
o2.a = 2

console.log(o1.a, o1 === o1.b) // 1 true
console.log(o2.a, o2 === o2.b) // 2 true

补一个新出的 Web API structuredClone() 支持循环引用深拷贝

用 lodash 的 _.cloneDeep()

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题