一般而言,深浅拷贝主要是用来形容JavaScript中,关于对象的克隆的。
浅拷贝即只克隆对象的引用,所以最终也是指向原对象在堆内存中的对象,无论是副本还是原对象修改了这个对象,都会导致堆内存中的数据发生相应的改变,因为它们的指针都是指向堆内存中的同一个对象。
而深拷贝则是直接克隆父对象在堆内存中的对象,最终是在堆内存中生成一个独立的,与父对象无关的新对象。深拷贝的对象虽然与父对象无关,但是却与父对象一致。当深拷贝完成之后,对父对象进行改变,并不会影响到深拷贝来的新对象,同理反之亦然。
浅拷贝只是拷贝一层,深拷贝拷贝多层。
浅拷贝实现的方式:
方式一:
let obj = {
name: 'Tom',
age: 20,
msg: {
job: 'coder',
},
arr: [1,2,3],
};
let newObj = {};
for(let k in obj) {
newObj[k] = obj[k];
}
console.log(newObj);//{name: 'Tom', age: 20, msg: {…},arr:[1,2,3]}
console.log(newObj === obj);//false
console.log(newObj.msg === obj.msg);//true
console.log(newObj.arr === obj.arr);//true
newObj.name = 'Jack';
console.log(newObj.name);//'Jack'
console.log(obj.name);//'Tom'
方式二:
let obj = {
name: 'Tom',
age: 20,
msg: {
job: 'coder',
},
arr: [1,2,3],
};
let newObj = {};
Object.assign(newObj,obj);
console.log(newObj === obj);//false
console.log(newObj.msg === obj.msg);//true
console.log(newObj.arr === obj.arr);//true
newObj.name = 'Jack';
console.log(newObj.name);//'Jack'
console.log(obj.name);//'Tom'
方式三:
let obj = {
name: 'Tom',
age: 20,
msg: {
job: 'coder',
},
arr: [1,2,3],
};
let newObj = {...obj};
console.log(newObj);//{name: 'Tom', age: 20, msg: {…},arr:[1,2,3]}
console.log(newObj === obj);//false
console.log(newObj.msg === obj.msg);//true
console.log(newObj.arr === obj.arr);//true
newObj.name = 'Jack';
console.log(newObj.name);//'Jack'
console.log(obj.name);//'Tom'
深拷贝实现的方式:
深拷贝是拷贝多层,这里用了递归函数。而对于函数的拷贝因为函数是一个实现相同功能的对象,所以不管是深、浅拷贝,拷贝的都是函数这个对象的指针也就是它的地址。
let obj = {
name: 'Tom',
age: 20,
msg: {
job: 'coder',
},
arr: [1,2,3],
fn: function(value) {
return value;
},
};
function deepCopy(item) {
let o = item instanceof Array ? [] : {};
for(let k in item) {
if(typeof item[k] != 'object') o[k] = item[k];
else o[k] = deepCopy(item[k]);
}
return o;
}
let newObj = deepCopy(obj);
console.log(newObj === obj);//false
console.log(newObj.msg === obj.msg);//false
console.log(newObj.arr === obj.arr);//fals
console.log(newObj.fn(1));//1