深浅拷贝只针对js中的复杂数据类型
一、浅拷贝
直接赋值就是一个浅拷贝的过程
let obj1 = {
a:1
}
let obj2 = obj1 //浅拷贝
我们知道,对象的引用存储在栈中,而对象本身存储在堆中,因此,赋值过程如下
这个时候,两个引用共同指向一块内存。这样会带来什么问题呢?
当一个对象的属性值发生变化时,另一个对象也随之受到影响
let obj1 = {
a:1
}
let obj2 = obj1 //浅拷贝
obj2.a = 2
console.log(obj1.a) //2
二、深拷贝
如果我只想复制一个对象而且不想让它对我原来的对象产生影响那该怎么办呢?
利用深拷贝!
1. JSON序列化和反序列化
JSON.parse(JSON.stringify(obj))
JSON.stringify() 将对象转化为字符串
JSON.parse() 将字符串转化为对象
let obj = {
a:1
}
let obj2 = JSON.parse(JSON.stringify(obj))
obj2.a = 2
console.log(obj); //{a:1}
console.log(obj2); //{a:2}
缺点:对象中值为undefined的属性和对象中的函数无法转化
let obj = {
a:1,
b:undefined,
c:()=>{
return 1
}
}
let obj2 = JSON.parse(JSON.stringify(obj))
console.log(obj2); //{a:1}
2.手动递归拷贝
function deep(obj){
//不是复杂数据类型
if(!(obj instanceof Object)) return obj;
//防御式拷贝 创建新数组或新对象
let targetObj = obj instanceof Array ? [] : {};
// 遍历对象中的所有属性
for(const key in obj){
//不是从原型上继承的
if(obj.hasOwnProperty(key)){
const value = obj[key]
//该属性的值还是复杂数据类型 递归deep函数
if(value instanceof Object){
targetObj[key] = deep(value)
} else {
targetObj[key] = value
}
}
}
return targetObj;
}