深浅拷贝

185 阅读2分钟

深浅拷贝

浅拷贝

  • 只会将对象的各个属性进行依次复制,并不会进行递归复制,也就是说只会赋值目标对象的第一层属性。
  • 浅拷贝是创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址 ,所以如果其中一个对象改变了这个地址,就会影响到另一个对象。
  • 浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存。

深拷贝

  • 不只拷贝目标对象的第一层属性,而是递归拷贝目标对象的所有属性。
  • 深拷贝是将一个对象从内存中完整的拷贝一份出来,从堆内存中开辟一个新的区域存放新对象,且修改新对象不会影响原对象。
  • 深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。

如何实现浅拷贝

  1. Object.assign()
     let obj1 = { person: {name: "guolaoshi", age: 26} };
     let obj2 = Object.assign({}, obj1);
  1. 展开运算符...
      let obj1 = { name: 'guolaoshi',age: 26}
      let obj2= {... obj1}
  1. Array.prototype.concat()
      let arr = [1, 3, { username: 'guolaoshi' }];
      let arr2 = arr.concat();
  1. Array.prototype.slice()
      let arr = [1, 3, { username: 'guolaoshi' }];
      let arr3 = arr.slice();

如何实现深拷贝

  1. JSON.parse(JSON.stringify())这种方法虽然可以实现数组或对象深拷贝,但不能处理函数和正则
  2. 手写深拷贝

如何解决循环引用的问题

  • 1、通过weakMap维护一个变量,变量中储存已经遍历过的对象2、每次递归时判断当前的参数是否已经存在于变量hash中,如果已经存在,就说明已经递归过该变量,就可以停止这次递归并返回上次递归该变量时的返回值