这篇文章就来带你了解一下深克隆与浅克隆,想要了解深克隆与浅克隆,就要先了解一下数据是怎样存储的。
对于基本数据的存储是直接将数据存在栈中的,而1对于引用数据类型的存储是将地址存储在栈中,数据存储在堆中
let a = 10;
let b = 100;
function fn() {
console.log(666);
}
let obj = {
name: 'lili',
age: 18
}
看看他们是如何存储的
深浅拷贝主要是针对引用数据类型的,先来说说什么是浅拷贝
浅拷贝就是将对象的地址复制过来,共用同一处内存,进行修改时会使原对象发生改变。
let obj = {
name: 'lili',
age: 18
}
let obj2 = obj;
这就是浅拷贝,只是将obj的地址复制给了obj2,obj2将里面的值进行修改了,而obj也会随之修改。
接下来说说深拷贝吧,深拷贝就是,在内存中开辟一块新的空间,将1原对象所有的值复制过去,注意复制的是值而不是地址,修改新对象中的属性,原对象不会受影响.
let obj = {
name: 'lili',
age: 18
}
let obj3 = {
name: 'lili',
age: 18
}
obj3.name = 'tom';
console.log(obj);
对于深克隆没有可以直接使用的方法,所以顺便来封装一下深克隆
第一种方法利用JSON的转换
var obj = {
a: 1,
b: 2,
c: {
d: 3,
e: [1, 2, 3, 4, 5]
},
f: [1, 3, 5, {},
[], 6
]
}
function deepcopy(origin) {
//将对象转换成字符串
let a = JSON.stringify(origin);
//再将其转换成对象,此时这已经是一个新对象了
let b = JSON.parse(a);
return b;
}
var res = deepcopy(obj);
obj.a = 10;
obj.c.d = 99;
obj.c.e[0] = 999999;
console.log(obj);
console.log(res);
第二种方法,利用Object.prototype.toString.call()来判断是什么类型的数据,如果是数组或者对象就将其循环复制,同样判断里面的元素是什么数据类型,利用递归完成拷贝。
function deepcopy(origin) {
let result;
//判断原来的数据是什么类型的
if (Object.prototype.toString.call(origin) == '[object Array]') {
result = [];
} else if (Object.prototype.toString.call(origin) == '[object Object]') {
result = {};
} else {
result = origin;
}
//将数据循环
for (let key in origin) {
// 判断数据里面的元素是什么类型
if (Object.prototype.toString.call(origin[key]) == '[object Array]' || '[object Object]') {
result[key] = deepcopy(origin[key]);
} else {
result[key] = origin[key];
}
}
return result;
}