function deepClone(data){
if(!isObject(data)){
// 非对象,直接拷贝
return data
}
let result = {}
if(data instance of Array){
result = []
}
for(let key in data){
if(data.hasOwnProperty(key)){
result[key] = deepClone(data[key])
}
}
return result
}
// 是否对象
function isObject(data){
return typeof data === 'Object' && data !== null
}
后续优化:
以上方法有较多缺陷,无法解决循环引用,Map和add类型数据的拷贝问题,以下为更好的解决方案。
/**
* map 此处解决循环引用问题
*/
function cloneDeep(obj:any,map=new WeakMap()):any{
if(obj == null || typeof obj !== 'object') return obj
// 解决循环引用问题
let mapVal = map.get(obj)
if(mapVal) return mapVal
let target:any = {}
map.set(obj,target)
if(obj instanceof Map){
target = new Map()
map.set(obj,target)
obj.forEach((k,v)=>{
const k1 = cloneDeep(k,map)
const v1 = cloneDeep(v,map)
target.set(k1,v1)
})
}
if(obj instanceof Set){
target = new Set()
map.set(obj,target)
obj.forEach((k)=>{
const a = cloneDeep(k,map)
target.add(a)
})
}
if(obj instanceof Array){
target = obj.map(val=>cloneDeep(val,map))
map.set(obj,target)
}
if(obj instanceof Object){
for(const key in obj){
const val = cloneDeep(obj[key],map)
target[key] = val
}
}
return target
}