前言
出差很久,终于回来了并且有时间更新了。。
刚开始学习前端的时候,我以为浅拷贝类似下面这种
let obj = {
name: "123",
};
let a = obj;
a.name='asd'
此时打印obj,发现obj.name=asd,而深拷贝则是改变a.name 但是obj.name并不会随之改变
后来才发现这种似乎不太准确,
深拷贝和浅拷贝只存在于复杂场景中,即对象的属性还是对象。
浅拷贝
只复制一层,当对象的属性为对象时,只复制其引用,当引用值发生变化时,也会跟着发生变化
首先定义两个数组和对象
let arr = [1, 2, [3, 4]];
let obj = {
a: 1,
b: { c: 2 },
};
let arr1 = [];
let obj1 = {};
浅拷贝方法1 :遍历
先看数组
for (let i = 0; i < arr.length; i++) {
arr1.push(arr[i]);
}
arr1[0]=0
arr1[2][0] = 0;
console.log(arr1, arr);
结果如下图
再来看对象
for (const key in obj) {
obj1[key] = obj[key];
}
obj1['a']=2
obj1['b']['c']=3
console.log(obj1,obj);
可以看出浅拷贝确实如上所述
当然还有很多浅拷贝方法,例如Object.assign,扩展运算符,concat ,slice等等
深拷贝
深拷贝就是当对象的属性也是对象的时候,改变其引用值,不会原对象不会更着变化
json.parse(JSON.stringify())
最常见的应该就是json.parse(JSON.stringify()) 但是这个方法无法复制函数和undefined
let a = {
name: undefined,
age() {},
};
copyObj = JSON.parse(JSON.stringify(a));
console.log(copyObj); //copyObj={}
递归
let test = {
name: "tom",
age: undefined,
dirve: () => {},
info: {
height: 180,
},
};
let deepClone = function (obj) {
let newObj=Array.isArray(obj)?[]:{}
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
if(obj[key]&& typeof obj[key]==='object'){
newObj[key]=deepClone(obj[key])
}else{
newObj[key]=obj[key]
}
}
}
return newObj
};
let copyObj=deepClone(test)
copyObj.name='jerry'
copyObj.info.height=170
console.log(test,copyObj)
上述的深拷贝和浅拷贝好像都有各种解释的方法,其实我也不确定哪一种是正儿八经的,我记得我之前看js高程的时候,好像有过我写的这一段解释,但是写这个文章的时候,却找不到了,可能我记忆出现了偏差
如果又更好的方法或者错误,希望有大佬指导一哈