本文记录深浅克隆的多种方法,其中总结浅克隆方法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