浅谈前端js对象的深拷贝和浅拷贝

时间: 作者:admin 浏览:

最近看了一篇关于对象拷贝的文章,说得太过于复杂,难以理解,其实深度拷贝和浅拷贝,拿json对象来说,我们可以很简单地去理解:

浅拷贝

浅拷贝简单理解就是,只能拷贝json对象的简单数据类型的属性,比如这种对象:

{a: 1, b: 'xx', c: true}//number/string/boolean

这种对象里面的属性经过浅拷贝,会重新分配空间,所以新旧对象属性修改不会相互影响;

而以下这种复杂对象,对象的属性值又是一个json对象:

{a: 1, b: {c: 2}}

浅拷贝的时候,a拷贝的是真实数据1,而b拷贝的是一个索引地址而非真实数据,所以新旧b的地址是同一个,都指向{c: 2}这个数据,因此浅拷贝以后,新对象的c值发生改变,则旧对象的c值也会跟着变,反之亦然;

”对一个对象进行浅拷贝,该对象下的基本类型属性会开辟新的空间,引用类型属性是还是指向同一块空间。”

也就是说,浅拷贝在拷贝的时候,对于地址引用类属性,只拷贝它的索引地址,而不是地址对应的真实数据,所以才叫“”;

可以验证数组类型是否一样,答案很明显;

下面是浅拷贝的例子:

  • Object.assign()
      let a = {b: 1,c: {d: 2}}
      let e = Object.assign({}, a)
    
      //1、改变a对象中的b,e对象的b不会变
      a.b = 2
      console.log(e.b)//1
    
      //2、改变a对象中的c,e对象中的c也不会变
      a.c = {d: 3}
      console.log(e.c)//{d: 2}
    
      //3、改变a对象第二层的对象d,e对象中的d也会变
      a.c.d = 3
      console.log(e.c.d)//3
    
      //4、反过来,改变e对象中的d,a对象中的d也会变,如下图
      e.c.d = 6
      console.log(a.c.d)//6
    

    图1

总结:浅拷贝会重新在堆中创建内存,拷贝新旧对象的基本数据类型互不影响,但拷贝新旧对象的引用类型因共享同一块内存,会相互影响。

深拷贝

理解了浅拷贝的意思,深拷贝就很容易理解了,深拷贝就相当于照着原json对象完完整整地重新创建了一个一模一样的新对象,不管什么类型的属性,都会重新分配新地址、新空间,所有属性跟原对象没有任何关系,无论怎么修改新对象或旧对象,都不会相互影响;

也就是说,深拷贝的所有属性,不管是基本数据类型还是引用类型,都重新分配新地址新索引,开辟新空间,与原对象彻底没关系了;

下面是深拷贝的例子:

  • JSON.parse(JSON.stringify())
      let a = {b: 1,c: {d: 2}}
      let e = JSON.parse(JSON.stringify(a))
    
      //1、改变a对象中的b,e对象的b不会变
      a.b = 2
      console.log(e.b)//1
    
      //2、改变a对象中的c,e对象中的c也不会变
      a.c = {d: 3}
      console.log(e.c)//{d: 2}
    
      //3、改变a对象第二层的对象d,e对象中的d也不会变
      a.c.d = 3
      console.log(e.c.d)//2
    
      //4、反过来,改变e对象中的d,a对象中的d也不会变,如下图
      e.c.d = 6
      console.log(a.c.d)//2
    

总结:深拷贝会从堆内存中开辟一个新的区域存放新对象,对对象中的子对象进行递归拷贝,拷贝前后的两个对象互不影响

前端新手交流群
欢迎加入web前端新手交流qq群:
734802480(已满)、 794324979

更多文章

栏目文章


Copyright © 2014-2022 seozhijia.net 版权所有-粤ICP备13087626号-4