对象(数组)的深克隆和浅克隆学习总结

977 阅读1分钟

本文记录深浅克隆的多种方法,其中总结浅克隆方法2种,深克隆方法3种。

浅克隆只克隆了对象的第一层,常见对象一般有3-4层,如果该对象为多维对象,即二维及以上的对象。这时就需要使用深克隆的方法。

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

一、浅克隆

方法1:使用对象的解构

对象的扩展运算符(...)用于取出对象的所有可遍历属性,拷贝到当前对象中。

let obj2 = {...obj}

方法2:使用循环

对象循环我们使用 for in 循环,但for in 循环会遍历到对象的继承属性,我们只需要它的私有属性,所以可以加一个判断方法:hasOwnProperty 保留对象私有属性。

let obj2 = {}
for (let i in obj){
    if(!obj.hasOwnProperty(i)) break;  // 这里使用continue也可以
    obj2[i] = obj[i]
}

二、深克隆

方法1:_.cloneDeep

lodash 提供了_.cloneDeep方法用于深克隆

let deep = _.cloneDeep(obj)
console.log(deep === obj) //false

方法2:JSON.stringify,JSON.parse

let obj2 = JSON.parse(JSON.stringify(obj))

存在的问题: 遇到正则会变为空对象,函数为空,日期会变为字符串

所以总结第三种方法

方法3:

function deepClone(obj){
    //过滤特殊情况
    if(obj === null) return null;
    if(typeOf obj !== "Object") return obj;
    if(obj instanceof RegExp){
        return new RegExp(obj)
    }
    //不直接创建空对象的目的是克隆的结果和之前保持相同的所属类
    let newObj = new Obj.constructor 
    //也可以这么写:
    //let newObj = obj instanceof Array?[]:{}
    for (let i in obj){
        if(obj.hasOwnProperty(i)){
            newObj[i] = deepClone(obj[i])
        }
    }
    return newObj;
}
let obj2 = deepClone(obj)
console.log(obj.c === obj2.c) //fasle