背景
在日常开发中,可能需要赋值一个对象;但是对象的赋值是将一个对象的引用赋值给另一个变量,是浅拷贝
let obj = { name: '张三', num: 5 }
let o = obj
o.num = 10
console.log('o:', o, 'obj:', obj) // obj.num = 10
console.log('o == obj:', o == obj) // true

但是我们的目的是修改赋值后的变量的属性值,不影响引用赋值的对象属性值。
解决方法
通过深拷贝,改变引入地址来解决
JSON
通过 JSON.parse(JSON.stringify()) 来实现深度拷贝。但是不能处理函数、undefined 值、循环引用
let obj = { name: '张三', num: 5 }
let o = JSON.parse(JSON.stringify(obj))
o.num = 10
console.log('o:', o, 'obj:', obj) // obj.num = 5
console.log('o == obj:', o == obj) // false

但是不能处理函数、undefined 值、循环引用。
let obj = {
name: '张三',
num: null,
count: undefined,
fn: function () {
console.log('function')
}
}
let o = JSON.parse(JSON.stringify(obj))
console.log('o:', o)

deepClone
通过递归循环对象的属性值,将键值对赋值给新的变量
实现:
function deepClone(source) {
if (!source || typeof source !== 'object') {
return source
}
const targetObj = Array.isArray(source) ? [] : {}
for (let key in source) {
if (source[key] && typeof source[key] === 'object') {
targetObj[key] = deepClone(source[key])
} else {
targetObj[key] = source[key]
}
}
return targetObj
}
使用:
let obj = { name: '张三', num: 5 }
let o = deepClone(obj)
o.num = 10
console.log('o:', o, 'obj:', obj) // obj.num = 5
console.log('o == obj:', o == obj) // false