深拷贝和浅拷贝的区别?如何实现深拷贝?

区别

const obj = { a: 1, b: { c: 2 } }

// 浅拷贝
const shallow = { ...obj }
shallow.b.c = 99
console.log(obj.b.c)  // 99(共享引用)

// 深拷贝
const deep = structuredClone(obj)
deep.b.c = 99
console.log(obj.b.c)  // 2(独立)

浅拷贝方法

const copy1 = { ...obj }              // 展开运算符
const copy2 = Object.assign({}, obj)   // Object.assign
const arrCopy = [...arr]               // 数组浅拷贝
const arrCopy2 = arr.slice()           // 数组浅拷贝

深拷贝方法

1. structuredClone(推荐,现代浏览器原生支持)

const clone = structuredClone(obj)
// 支持循环引用、Date、RegExp、Map、Set 等
// 不支持函数、Symbol、DOM 节点

2. JSON 序列化(简单但有局限)

const clone = JSON.parse(JSON.stringify(obj))
// ❌ 不支持:undefined、function、Symbol、循环引用、Date→字符串、RegExp→空对象

3. 手写深拷贝

function deepClone(obj, map = new WeakMap()) {
  if (obj === null || typeof obj !== 'object') return obj
  if (obj instanceof Date) return new Date(obj)
  if (obj instanceof RegExp) return new RegExp(obj)
  if (obj instanceof Map) {
    const clone = new Map()
    map.set(obj, clone)
    obj.forEach((v, k) => clone.set(deepClone(k, map), deepClone(v, map)))
    return clone
  }
  if (obj instanceof Set) {
    const clone = new Set()
    map.set(obj, clone)
    obj.forEach(v => clone.add(deepClone(v, map)))
    return clone
  }

  // 处理循环引用
  if (map.has(obj)) return map.get(obj)

  const clone = Array.isArray(obj) ? [] : {}
  map.set(obj, clone)

  for (const key of Reflect.ownKeys(obj)) {
    clone[key] = deepClone(obj[key], map)
  }
  return clone
}

各方法对比

方法 循环引用 函数 Date/RegExp 性能
structuredClone ✅ ❌ ✅ 好
JSON.parse/stringify ❌ ❌ ❌ 中
手写 deepClone ✅ ✅ ✅ 可控

同分类其他题目