什么是深复制和浅复制
首先在在进入主题之前需要知道:
- 在js中,基本变量和引用对象的引用地址都是存在栈中的
- 引用对象的值内容都是存在堆中的
因此:
浅复制其实就是引用对象指向栈中同一个引用地址,当被复制的对象改变时,复制的对象也会随之改变,依旧受被复制对象的牵扯(除非原来的指向了别的地址),相互牵连
深复制就是在栈中生成一个新的地址指向原来的堆中的值内容,就是不被牵扯,自成一派
产生深复制和浅复制的原因
首先深复制和浅复制一般只指Object对象,在复制中,浅复制是将值指向了和被复制对象值的同一个地址,所以互相牵扯,而深复制是又创建了一个新的地址,将被复制对象地址上的内容放到了新的地址上,所以两个地址相互不影响
注:这里的内存地址内容是指存在栈中的引用地址
浅复制相互影响
let a = [1,2,3,4];
let c = a;
a[0] = 2;
console.log(c); //[2,2,3,4]
c[2] = 10;
console.log(a); //[2,2,10,4]
深复制
方法一:使用递归,对每个值进行复制
function deepClone(obj) {
if (!obj) return;
//判断参数是数组还是对象,然后创建作为复制存储的空数组或者空对象
let cloneObj = Array.isArray(obj) ? [] : {};
if (typeof obj === 'object') {
for(item in obj) {
//判断obj子元素即下一层是否为对象,如果是,递归复制
if(obj[item] && typeof obj[item] ==="object"){
cloneObj[item] = deepClone(obj[item]);
//如果不是,简单复制
}else{
cloneObj[item] = obj[item];
}
}
}
return cloneObj;
}
let a = [1,2,[11,12],4,5];
let c = deepClone(a);
a[2][0] = 3;
console.log(a); //[1,2,[3,12],4,5]
console.log(c); //[1,2,[11,12],4,5]
方法二:使用JSON.stringify和JSON.parse
function deepClone(obj){
let objString = JSON.stringify(obj); //从对象解析出字符串
let cloneObj = JSON.parse(objString); //将字符串解析成json对象
return cloneObj
}
let a = [1,2,[11,12],4,5];
let c = deepClone(a);
a[2][0] = 3;
console.log(a); //[1,2,[3,12],4,5]
console.log(c); //[1,2,[11,12],4,5]