先说说深拷贝和浅拷贝
- 浅拷贝
所谓浅拷贝,就是只复制最外一层,里面的都还是相同引用
// 浅拷贝
const a = { name: 'xiaoming', age: 23 }
const b = {}
for (let key in a){
b[key] = a[key]
}
console.log(b) // { name: 'xiaoming', age: 23 }
console.log(b === a) // false
console.log(b.name === a.name) // true
- 深拷贝
深拷贝,是将一个对象拷贝到另一个新变量,这个新变量指向的是一块新的堆内存地址
// 深拷贝
function cloneDeep(target) {
// ...dosomething 实现深拷贝
}
const a = { name: 'xiaoming', age: 23 }
const b = cloneDeep(a)
console.log(b) // { name: 'xiaoming', age: 23}
console.log(b === a) // false
console.log(b.name === a.name) // false
- 深拷贝实现代码
常用版本
function cloneDeep(target) {
return JSON.parse(JSON.stringify(target))
}
const a = { name: 'xiaoming', age: 23 }
const b = cloneDeep(a)
console.log(b) // { name: 'xiaoming', age: 23 }
console.log(b === a) // false
虽然大多数时候这么使用是没问题的,但这种方式在工作中还是有很多问题
1、对象中有字段值为undefined
,转换后则会直接字段消失
2、对象如果有字段值为RegExp
对象,转换后则字段值会变成{}
3、对象如果有字段值为NaN、+-Infinity
,转换后则字段值变成null
4、对象如果有环引用
,转换直接报错
升级一下
function cloneDeep(target) {
const temp = {}
for (const key in target) {
temp[key] = target[key]
}
return temp
}
const a = { name: 'xiaoming', age: 23 }
const b = cloneDeep(a)
console.log(b) // { name: 'xiaoming', age: 23 }
console.log(b === a) // false
看起来不错了,但是遇到层数比较深的还是不可以,在优化一下,递归一下。
function cloneDeep(target) {
// 基本数据类型直接返回
if (typeof target