深拷贝
引用类型的深拷贝方法,可解决深层嵌套、循环引用问题
点击查看代码
js
function deepClone(target) {
// 记录所有对象的引用
const map = new WeakMap()
function isObject(source) {
if (!source || typeof source !== 'object') {
return false
} else {
return true
}
}
function clone(target) {
if (!isObject(target)) return
let result = null
// 检查循环引用,存在引用过的则直接返回
const referenced = map.get(target)
if (referenced) {
return referenced
}
// 区分数据类型
result = Array.isArray(target) ? [] : {}
// 记录当前引用值,result为引用地址,值会被后续操作改变
map.set(target, result)
Object.keys(target).forEach(key => {
if (isObject(target[key])) {
result[key] = clone(target[key])
} else {
result[key] = target[key]
}
})
return result
}
return clone(target)
}
测试
js
/* 深层嵌套 */
let obj = { name: 'xxx', arr: [1, 2, 3], sec: { content: { age: 18 } }, fn: () => {} }
let cloneObj = deepClone(obj)
obj.sec.content.age = 22
obj.arr.push(4)
console.log(obj, 'obj')
console.log(cloneObj, 'cloneObj')
/* 循环引用 */
let a = { name: 'aa', arr: [3, 4] }
let b = { name: 'bb' }
a.child = b
b.parent = a
console.log(a, 'source')
let cloneA = deepClone(a)
console.log(cloneA, 'clone')