深拷贝和浅拷贝
JS复杂数据类型分别保存在栈内存(变量标识符和堆中对象指针)和堆内存,因此用=赋值时复制的是栈内存的内容,称为浅拷贝;
通过某种方式将复杂数据类型堆内存中的值拷贝给另一个复杂对象称为深拷贝。
深拷贝实现
以此对象为例:
let obj = {
text: 'abc',
num: 123,
undefin: undefined,
func: () => {
console.log('func')
},
exp: new RegExp(/a/),
deepobj: {
name: "a"
}
}
JSON拷贝: 无法拷贝undefined、function、RegExp
JSON.parse(JSON.stringify(obj))
Object.assign: 只能拷贝第一层基本类型
let assignObj = Object.assign({}, obj)
assignObj.deepobj.name = "b" // 影响原对象
通过递归实现深度拷贝:
function deepClone(target) {
let result
if (typeof target === 'object') { // 如果当前需要深拷贝的是一个对象
if (Array.isArray(target)) { // 如果是一个数组
result = [] // 将result赋值为一个数组,并且执行遍历
for (let i in target) {
result.push(deepClone(target[i])) // 递归克隆数组中的每一项
}
} else if (target === null) {
result = null // 判断如果当前的值是null,直接赋值为null
} else if (target.constructor === RegExp) {
result = target // 判断如果当前的值是一个RegExp对象,直接赋值
} else {
result = {} // 否则是普通对象,直接for in循环,递归赋值对象的所有值
for (let i in target) {
result[i] = deepClone(target[i])
}
}
} else {
result = target // 如果不是对象,就是基本数据类型,直接赋值
}
return result // 返回最终结果
}