jQuery —— 深拷贝和浅拷贝

当须要一个对象想把另外一个对象的内容复制一份给本身时,就出现了拷贝的问题,进而引出深拷贝和浅拷贝。jQuery中有拷贝对象的方法javascript

$.extend([deep],targetobj,obj[,obj1][,obj2]):targetObj拷贝objjava

 方法中有三个参数数组

deep:若是值为true,为深拷贝,不然浅拷贝。默认是浅拷贝spa

targetObj:拷贝的对象code

obj:被拷贝的对象对象

这个方法支持多个对象的拷贝,因此后面是多个对象,我没有尝试多个对象的拷贝,这里就不涉及了。blog

介绍完基本的概念,接下来就来操做看看吧。ip

先建立两个对象内存

var obj = {
                name: "kk",
                age: 18,
                wife: {
                    name: "tt",
                    height: 165
                }
            };
            var targetObj = {
                name: "hh",
                wife: {
                    name: "ww",
                    age: 18
                }
            };

 

浅拷贝 —— 第一个参数为false或者默认get

// 浅拷贝
            // targetObj 拷贝的是obj在栈内存的地址 指向同一个堆空间的对象
            $.extend(targetObj, obj);
            obj.wife.height = 170; // 都变化了
            targetObj.wife.name = "ctt";
            console.log(obj);
            console.log(targetObj);

浅拷贝的实质就是把被拷贝对象的内容复制一份给本身。当复制简单数据类型时,就直接把属性和属性值直接复制一份,若是遇到相同的属性,拷贝对象的属性值会覆盖掉本身本来的属性值(“hh”变成了“kk”);遇到复杂数据类(这里的wife属性),通常是指对象和数组,是直接复制wife在栈空间的地址,这样就意味着obj中的wife和targetObj中的wife指向的是同一个对象,对同一个对象的引用。在咱们更改targetObj或者obj中的wife对象的属性时,两者都会产生变化。这就是浅拷贝。

看个图,会更形象。

 

深拷贝 —— 第一个参数为true

// 深拷贝
            // targetObj 拷贝的是obj在栈内存的地址 targetObj在堆空间中从新开辟一个空间指向本身对象的引用
            $.extend(true, targetObj, obj);
            targetObj.wife.height = 170; // 互不影响
            obj.wife.height = 165;
            obj.age = 22;
            console.log(obj);
            console.log(targetObj);

 

 

targetObj.name = "target";
            targetObj.wife.name = "targetww";

 

深拷贝的核心:只是把被拷贝对象的内容复制一份,目标对象本身在栈空间开辟一块空间,遇到复杂数据类型时本身在堆空间中开辟一块空间,引用本身的对象。当更改值时,各改各的值,互不影响,两者只是看起来长的很像可是是两个不一样的对象。targetObj拷贝obj的wife对象时,首先会在栈空间存放本身的地址,再去堆空间开辟一块空间,地址指向堆空间的对象。这样实现了不一样的对象引用不一样的对象,达到两个对象的分离,互不影响。复制的过程当中,会出现覆盖值得状况,可是没有关系在复制完毕以后能够本身手动更改属性值的。

深拷贝最后获得的是两个全完不一样的对象,只是看起来同样,其实是两个不一样的对象。

 

实现的内部图

 

两个内部实现的图,很清晰的体现了拷贝的核心点。