对象(数组)的深克隆和浅克隆

160 阅读1分钟

浅克隆:只拷贝对象的引用,不深层次的拷贝对象的值,导致任何一个修改都会使得所有对象的值修改。

let obj = {
    a: 100,
    b: [10, 20, 30],
    c: {
        x: 10
    },
    d: /^\d+$/    //正则
}


//方法一,循环遍历
let obj2 = {};
for(let key in obj) {
    if(!obj.hasOwnProperty(key)) break;
    obj2[key] = obj[key];
}

//方法二,es6
let obj2 = {
    ...obj
}


深克隆:不会拷贝引用类型,而是将引用类型的值全部拷贝,解决引用错乱的问题。

//先将其转成字符串,然后再转回对象
//问题:参数值为正则和函数无法使用此方法,JSON.stringify()会将正则转化为空对象,
//如果是函数转化后不会显示
let obj2 = JSON.parse(JSON.stringify(obj))

//方法二 递归法
function deepClone(obj) {
    //过滤特殊情况
    if(obj === null) return null; //判断是否为空
    if(typeof obj !== "object") return obj; //判断是否为对象
    // 判断正则
    if(obj instanceof RegExp) {
        return new RegExp(obj);
    }
    // 判断日期类型
    if(obj instanceof Date) {
        return new Date(obj);
    }
    // 不直接创建空对象 目的:克隆的结果和之前保持相同的属性类
    let newObj = new.obj.constructor; //创建对象,为了兼容传入的是实例
    for(let key in obj){
        if (obj.hasOwnProperty(key)) {
            newObj[key] = deepClone(obj[key]);
        }
    }
    
    return newObj;
}
let obj2 = deepClone(obj);