浅拷贝和深拷贝理解和总结

曾经在网上看到些关于深拷贝和浅拷贝的文章,让我误认为浅拷贝即新定义的值只要与被拷贝的值引用同一个堆地址,那么它就是浅拷贝,应该有不少跟我一样的吧。直到我看到mdn上关于Array.prototype.slice() 的描述:

  slice() 方法返回一个新的数组对象,这一对象是一个由 begin和 end(不包括end)决定的原数组的浅拷贝

这与我理解中的浅拷贝有所区别,抱着探究的心理去探究,终于觉得应该是理解了之间的区别,直接上代码(这里只讨论引用数据类型,原始数据类型都存在于栈中,不可改变):

  

var obj = {
            name:'zhangsan',
            age:'21',
            children:['zhang1','zhang2']
        }

        var obj1 = obj;   // 引用

        var obj2 = shallowCopy(obj);  // 浅拷贝

        function shallowCopy(obj){
            var temp = {}
            for(var item in obj){
                temp[item] = obj[item];
            }
            return temp;
        }

        var obj3 = deepCopy(obj);  // 深拷贝
     // 深拷贝方式有几种,这里采用递归 function deepCopy(obj){ var temp = null; if(typeof obj === 'object' && obj !== null){ temp = obj instanceof Array ? [] : {}; for(var item in obj){ temp[item] = deepCopy(obj[item]); }; return temp; }else{ return obj; } } // 因为我知道obj3不会影响obj1,所以先对obj3进行操作,利于展示(懒) obj3.name = 'wangwu'; obj3.children.push('zhang5'); obj1.name = 'lisi'; obj2.age = '25'; obj1.children.push('zhang3'); obj2.children.push('zhang4'); console.log('obj===',obj); console.log('obj1===',obj1); console.log('obj2===',obj2); console.log('obj3===',obj3);

  

打印结果如下:

  

 

由此,可以得出下面的总结

  引用:    在栈内存中新增一个值(obj1),但是与被复制的值(obj)实际引用的同一个堆地址,修改obj1的name和children都会影响obj;

  浅拷贝: 只复制原对象的第一层,并不包含子对象,修改obj2的name不会影响obj,修改obj2的children会影响obj;

  深拷贝: 将原对象所有的属性全复制过来,修改obj3的name和children都不会影响obj。

posted @ 2019-03-19 10:58  lisiyuan  阅读(709)  评论(0编辑  收藏  举报