首先先了解一下概念:
浅拷贝:浅拷贝只会拷贝对象的第一层属性,如果这些属性是对象,则不会对这些对象进行拷贝,而是直接复制对象的引用。这意味着,对于浅拷贝后的对象,如果原对象的属性值发生了变化,浅拷贝后的对象的属性值也会跟着发生变化。
//浅拷贝
const obj1 = {
name: "老六",
age: 18,
address:{
city:"北京",
},
fn: function(){
console.log(123);
}
}
const obj2 = obj1;
obj2.address.city = "广州"
console.log(obj1);
console.log(obj2);
这就是简单的浅拷贝,结果如下,obj2的改变使obj1也跟着改变。
如何实现只改变obj2而obj1不跟随改变,这种实现就可以理解为深拷贝。下面给出深拷贝的定义:
深拷贝:在进行深拷贝时,会拷贝所有的属性,并且如果这些属性是对象,也会对这些对象进行深拷贝,直到最底层的基本数据类型为止。这意味着,对于深拷贝后的对象,即使原对象的属性值发生了变化,深拷贝后的对象的属性值也不会受到影响。
// 深拷贝1
const obj1 = {
name: "老六",
age: 18,
address:{
city:"北京",
},
fn: function(){
console.log(123);
}
}
const obj2 = deepClone(obj1);
obj2.address.city = "广州"
console.log(obj1);
console.log(obj2);
function deepClone(obj){
return JSON.parse(JSON.stringify(obj))
}
这样就可以实现所想要的结果了
但是发现这种深拷贝后的fn会消失了,那么就要用到另一种方法了:
// 深拷贝2
const obj1 = {
name: "老六",
age: 18,
address:{
city:"北京",
},
fn: function(){
console.log(123);
}
}
const obj2 = deepClone(obj1);
obj2.name = "老七";
obj2.address.city = "广州";
console.log(obj1);
console.log(obj2);
function deepClone(obj){
if (typeof obj !== "object" || obj == null){
return obj;
}
let res = obj instanceof Array ? [] : {};
for (let key in obj){
res[key] = obj[key] //无递归
}
return res;
}
这样的结果就fn就不会消失了,但是我们看下面结果发现地址广州又变成浅拷贝了,因为地址也是一个对象,因此容易想到递归就可以解决了,
递归方法:
// 深拷贝(递归)
const obj1 = {
name: "老六",
age: 18,
address:{
city:"北京",
},
fn: function(){
console.log(123);
}
}
const obj2 = deepClone(obj1);
obj2.name = "老七";
obj2.address.city = "广州";
console.log(obj1);
console.log(obj2);
function deepClone(obj){
if (typeof obj !== "object" || obj == null){
return obj;
}
let res = obj instanceof Array ? [] : {};
for (let key in obj){
res[key] = deepClone(obj[key]) //递归
}
return res;
}
结果就是我们想要的神拷贝了