数据类型、浅拷贝、深拷贝

108 阅读2分钟

个人笔记-仅供参考

深浅拷贝

数据类型

基本数据类型

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));