Words etch cherished moments.
OG

javascript对象深拷贝和浅拷贝

1,584 words, 4 min read
2019/07/15 AM
327 views

数据的复制是一个常见需求,而理解深拷贝与浅拷贝的区别对于避免意外的数据修改至关重要。

#浅拷贝与深拷贝的区别

#浅拷贝

浅拷贝只复制对象的第一层属性,如果源对象的属性是基本类型(如字符串、数字、布尔值等),拷贝的就是这些值的一个副本;但如果属性是引用类型(如数组、对象等),拷贝的则是这个引用的副本,也就是说源对象和拷贝对象会共享同一块内存地址。因此,对引用类型属性的修改会影响到原对象。

#深拷贝

深拷贝不仅复制第一层属性,还会递归地复制所有层级的嵌套对象,直到遇到基本类型为止。这样,无论对象的结构有多复杂,深拷贝都会创建一个完全独立的新对象,源对象和拷贝对象之间没有任何关联,修改拷贝对象不会影响到原对象。

#如何实现深浅拷贝

#实现浅拷贝

  1. Object.assign()
          
  • 1
  • 2
const obj1 = { a: 1, b: { c: 2 } }; const obj2 = Object.assign({}, obj1);

注意:Object.assign()只能处理第一层属性的浅拷贝。

  1. Spread Operator (扩展运算符)
          
  • 1
  • 2
const obj1 = { a: 1, b: { c: 2 } }; const obj2 = { ...obj1 };

扩展运算符同样只进行浅拷贝。

#实现深拷贝

  1. JSON.parse() 和 JSON.stringify()

这是最简单但有限制的方法,适用于简单对象,不支持函数、循环引用等情况。

          
  • 1
  • 2
const obj1 = { a: 1, b: { c: 2 } }; const obj2 = JSON.parse(JSON.stringify(obj1));
  1. 递归实现深拷贝

对于更复杂的情况,可以手动实现一个递归函数来完成深拷贝。

          
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
function deepClone(obj, hash = new WeakMap()) { if (obj === null || typeof obj !== 'object') return obj; if (hash.has(obj)) return hash.get(obj); let cloneObj = Array.isArray(obj) ? [] : {}; hash.set(obj, cloneObj); for (let key in obj) { if (obj.hasOwnProperty(key)) { cloneObj[key] = deepClone(obj[key], hash); } } return cloneObj; } const obj1 = { a: 1, b: { c: 2 } }; const obj2 = deepClone(obj1);

这个方法可以处理包括循环引用在内的复杂情况,但性能开销相对较大。

#总结

浅拷贝和深拷贝的选择取决于具体应用场景。如果你的数据结构简单,且不需要原对象与拷贝对象完全隔离,浅拷贝是一个快速简便的选择。而当你处理复杂对象,特别是包含多层嵌套或特殊类型的对象时,深拷贝能提供更加安全、可靠的数据复制方式。通过上述方法,你可以灵活地在JavaScript中实现所需的拷贝策略。

Creative Commons BY-NC 4.0
https://zhangwurui.cn/article/56
0/0comments
Guest
Start the discussion...
Be the first to comment