美文网首页
深浅拷贝你知道多少?(针对引用类型Object)

深浅拷贝你知道多少?(针对引用类型Object)

作者: 跟屁虫丶 | 来源:发表于2020-01-02 23:58 被阅读0次

    * 变量引用值,

    * 地址存储值。

    * 对象的拷贝: 将一个对象赋值给另外一个对象, 我们称之为对象的拷贝

    * 浅拷贝: (只需要使用赋值运算符(=)即可)

    原因: 浅拷贝只是对对象的引用地址进行了拷贝,并没有开辟新的堆栈,拷贝后,两个对象指向的是同一个引用地址,所以修改其中一个对象的属性,另一个对象的属性也会改变。

        简单来说就是 两个变量 指向同一个 内存地址。所以一旦在 新变量 修改 变量值 ,会影响被拷贝的原变量。因为他们指向同一个内存地址。

        code: 

            var ch = {

                name: "chenhang",

                size: "shou"

            };

            //将原对象直接赋值给新变量

            var ch2 = ch;

            ch2.name = "小基佬";

            console.log(ch, ch2);

    * 深拷贝: 

        复制了一份内存的值,同时开辟了一块 新内存 存放这个值,值相同,但是内存地址不相同。如果修改新变量的值,不会对被拷贝的原变量产生影响。

        code:

            var a = {

                name: "zouhaohao",

                age: "22",

                sex: "boy"

            }

            //JSON.stringify 将对象转化成字符串   JSON.parse 将字符串转化成对象 

            var hh = JSON.parse(JSON.stringify(a));

            hh.name  = "聪明的小伙子";

            console.log(a, hh);

    * 网上流传Object.assign能够实现对象的深拷贝、slice和concat能够实现数组的深拷贝,经过测试,这些都只是披着深拷贝的外衣的浅拷贝。

        * 如何理解: 【披着深拷贝的外衣的浅拷贝】 ?

            - 如果该对象属性的值并没有引用类型时,这三个方法均能实现深拷贝,实现对值的拷贝。

            - 一旦对象属性的值为引用类型时,只会对该值的引用地址进行拷贝。 这又回到了浅拷贝。

            code: 

            var obj = { age: '11', parent: { father: 'XX', mother: 'XX' } };

            var newObj = Object.assign({}, obj);  //将obj中的参数复制到{}中,故参数顺序不能反

            obj.age = '12';

            obj.parent['father'] = 'YY'; //对象里面的对象修改了。

            console.log(obj);      // obj: { age: '12', parent: { father: 'YY', mother: 'XX' } } 

            console.log(newObj);   // newObj: { age: '11', parent: { father: 'YY', mother: 'XX' } 实现了对obj对象的简单属性的深拷贝 但是对象的对象属性确是浅拷贝。

        总结一下: MDN都说了Object.assign方法只会拷贝源对象自身的并且可枚举的属性到目标对象。是用来合并对象的,人家拷贝的是属性值,假如源对象的属性值是一个对象的引用,那么它也指向那个引用(这不是典型的浅拷贝的本质吗,指向同一个引用,即引用被修改了,指向所有该引用的所有属性值都将修改.)

    * 【如何实现真正的深拷贝】?

        1. JSON.parse()

            网上流传的一个黑科技,使用var newObj = JSON.parse(JSON.stringify(obj))可以实现对象的深拷贝,但是该方法存在一些问题:

            - 无法作用于函数,RegExp特殊对象,不过对这些进行深拷贝,我觉得并不需要,如果有需要对函数进行深拷贝用途的地方,欢迎...

            - 会抛弃对象的constructor,所有的构造函数都会指向Object。

            - 对象有循环引用,会报错。

    相关文章

      网友评论

          本文标题:深浅拷贝你知道多少?(针对引用类型Object)

          本文链接:https://www.haomeiwen.com/subject/nskgoctx.html