当须要一个对象想把另外一个对象的内容复制一份给本身时,就出现了拷贝的问题,进而引出深拷贝和浅拷贝。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对象时,首先会在栈空间存放本身的地址,再去堆空间开辟一块空间,地址指向堆空间的对象。这样实现了不一样的对象引用不一样的对象,达到两个对象的分离,互不影响。复制的过程当中,会出现覆盖值得状况,可是没有关系在复制完毕以后能够本身手动更改属性值的。
深拷贝最后获得的是两个全完不一样的对象,只是看起来同样,其实是两个不一样的对象。
实现的内部图
两个内部实现的图,很清晰的体现了拷贝的核心点。