- 浅拷贝
浅拷贝出现的前提:引用类型的数据(对象和数组)
- 浅拷贝当把obj1赋值给obj2的时候,再去通过obj2修改里面的属性obj1会跟着一起变。
const obj1 = {
a= 1
}
const obj2 = obj1
obj2.a = 2
console.log(obj1.a, obj2.a) //2 2
- 深拷贝
- 对于基本数据类型的赋值可以理解为深拷贝。将a的值赋给b相当于重新开辟了内存空间来存放b,修改b的值将不会影响到a的值。
const a = 1
const b = a
b = 2
console.log(a, b) //1 2
- 如果想要对引用类型进行深拷贝使用JSON.parse(JSON.stringify(obj1))来实现。但是这种方法会有缺点:数据类型为function或者数据值为undefined时无法复制。
const obj1 = {
a: 1,
b: undefined,
c: [1,2,3],
d: () => {}
}
const obj2 = JSON.parse(JSON.stringify(obj1))
obj2.a = 2
obj2.c[0] = 11
console.log(obj1, obj2) //会发现obj1不会发生改变,obj2中缺少b d属性
- 还可以使用Object.assign({}, obj1),它的缺点是:只能拷贝一级属性二级以上的属性(引用类型)就是浅拷贝。
const obj1 = {
a: 1,
b: undefined,
c: [1,2,3],
d: () => {}
}
const obj2 = Object.assign({}, obj1)
obj2.a = 2
obj2.c[0] = 11
console.log(obj1, obj2) //会发现obj1.c会跟随obj2.c一起改变
- 扩展运算符(...),它的缺点也是:只能拷贝一级属性二级以上的属性(引用类型)就是浅拷贝。
const obj1 = {
a: 1,
b: undefined,
c: [1,2,3],
d: () => {}
}
const obj2 = {...obj1}
obj2.a = 2
obj2.c[0] = 11
console.log(obj1, obj2) //会发现obj1.c会跟随obj2.c一起改变
function CloneDeep (obj, map = New map){
if(typeOf obj !==
return obj
} else {
const obj_ = arr.isArry(obj) ? [] : {}
if(!map.get(obj)) {
map.set(obj, obj_)
for(let key in obj) {
obj_ = CloneDeep(obj[key], map)
}
return obj_
} else {
return map.get(obj)
}
}
}
- 补充:对于数组中的slice, concat也可以进行深拷贝,确定同样是:只能拷贝一级属性二级以上的属性(引用类型)就是浅拷贝。