深拷贝和浅拷贝两者的区别:
假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明这是浅拷贝,拿人手短,如果B没变,那就是深拷贝,自食其力。
用堆(heap)和栈(stack)来说:
浅拷贝是:B拷贝A时,AB指向同一个堆中的值;
深拷贝是:B拷贝A时,B会在堆中开辟出一个新的内存,与A并存。
深拷贝是在堆内存中开辟一个新的内存出来存储数据,是将对象和值复制过来,两个对象间互不影响。
浅拷贝是复制对象有引用地址,两个对象指向同一个地址,一个对象更改时,另一个对象也会更改。
浅拷贝,值的引用
var a = [1, 2, 3, 4, 5];var b = a;a[0] = 2console.log(a);console.log(b);//因为b浅拷贝a, ab指向同一个内存地址(堆内存中存的值)//b会随着a的变化而变化//[2, 2, 3, 4, 5]//[2, 2, 3, 4, 5]

深拷贝,两都互不影响:
function clone(source) {var target = {};for(var i in source) {if (source.hasOwnProperty(i)) {//Object的hasOwnProperty()方法返回一个布尔值,判断对象是否包含特定的自身(非继承)属性。//hasOwnProperty()这个方法会查找一个对象是否有某个属性,但是不会去查找它的原型链,来自:https://blog.csdn.net/i_dont_know_a/article/details/84324051//简单来说hasOwnProperty()就是判断自身属性是否存在原型(返回false)中还是实例(返回true)中target[i] = source[i];}}return target;}var obj = {a:1,b:2}var obj2 = clone(obj)obj2.a = 2// obj2 {a: 2, b: 2}// obj {a: 1, b: 2}

以上的两个实例只是对单层数据格式的实现
递归的方式实现深拷贝:
function clone(source) {var target = {};for(var i in source) {if (source.hasOwnProperty(i)) {if (typeof source[i] === 'object') {target[i] = clone(source[i]); // 注意这里} else {target[i] = source[i];}}}return target;}var obj = {a:1,b:2,c:3}var obj2 = clone(obj)
function deepClone(obj){let objClone = Array.isArray(obj)?[]:{};// Array.isArray() 方法用于判断一个对象是否为数组。if(obj && typeof obj==="object"){for(key in obj){if(obj.hasOwnProperty(key)){//判断obj子元素是否为对象,如果是,递归复制if(obj[key]&&typeof obj[key] ==="object"){objClone[key] = deepClone(obj[key]);}else{//如果不是,简单复制objClone[key] = obj[key];}}}}return objClone;}let a=[1,2,3,4],b=deepClone(a);a[0]=2;console.log(a,b);
JSON对象的stringify和parse实现深拷贝(缺点:无法复制函数类型):
function deepClone(obj){let _obj = JSON.stringify(obj),objClone = JSON.parse(_obj);return objClone}let a=[0,1,[2,3],4],b=deepClone(a);a[0]=1;a[2][0]=1;console.log(a,b);a 输出 [1,1,[1,3],4]b 输出 [0,1,[2,3],4]
JQuery的extend方法
$.extend( [deep ], target, object1 [, objectN ] )
deep表示是否深拷贝,为true为深拷贝,为false,则为浅拷贝
target 为Object类型 目标对象,其他对象的成员属性将被附加到该对象上。
object1 objectN可选。 Object类型 第一个以及第N个被合并的对象。
let a=[0,1,[2,3],4],b=$.extend(true,[],a);a[0]=1;a[2][0]=1;console.log(a,b);a 输出 [1,1,[1,3],4]b 输出 [0,1,[2,3],4]
参考自:https://blog.csdn.net/HiSen_CSDN/article/details/103188104
