深浅拷贝
数据类型
基本数据类型
String、Number、Boolean、null、undefined、symbol(es6)、Bigint(es10)
引用数据类型
Object、Array、function
浅拷贝
复制基本数据类型的方式为浅拷贝
Object.assign({},obj);
let a = 1;
let b = a;
console.log(`${a} : ${b}`);
a = 2;
console.log(`${a} : ${b}`);
// 基本数据类型 名 值 存储在栈中 修改
// name | val
// a | 1
// b | a
// 当声明b复制a值时,会在栈内存中开辟一个新的内存
// 将a值修改为2时,b的值不会根据a值的变化而变化,即不会影响b的值
// 以上称为 ”浅拷贝“
深拷贝
解决复制引用数据类型的方式称为深拷贝
JSON.parse(JSON.stringify(obj));
let a1 = [0,1,2,3];
let b1 = a1;
console.log(`${a1} : ${b1}`);
a1[0]=1;
console.log(`${a1} : ${b1}`);
// 引用数据类型:Object Array Function
// 当声明引用数据类时
// 声明的变量名(name)存放在栈内存中,(val)则为引用地址 指向堆内存中
// name | val 堆内存的val
// a1 | 堆内存地址 ------> val
// b1 | 堆内存地址 ------> val
// 当声明a1时,先在栈中生成一个内存,同时在堆中也生成一个内存,栈中的val指向堆内存
// 当修改a1中的值时,堆中的值发生变化。此时b1中栈内存的val和a1中的val引用的是同一个堆内存。所以此时的b1的随a1的值变化。达不到复制拷贝的效果
// 可以复制引用数据类型的方法称为”深克隆“
// 深拷贝
function deepClone(obj) {
// 校验参数是否为引用类型:过滤特殊类型 null
if(!obj) return;
let objClone = Array.isArray(obj)?[]:{};
if(typeof obj === 'object'){
for (const key in obj) {
if (Object.hasOwnProperty.call(obj, key)) {
if(obj[key] && typeof obj[key] === 'object'){
objClone[key] = deepClone(obj[key]);
}else {
objClone[key] = obj[key]
}
}
}
}
return objClone;
}
let c1 = deepClone(a1);
a1[1]=9;
console.log(`${a1} : ${c1}`);
let a2 = [1,2,[2,3],4];
let b2 = deepClone(a2);
a2[0]=0;
a2[2][1]=0;
console.log('a2',JSON.stringify(a2,null,3));
console.log('b2',JSON.stringify(b2,null,3));