一、使用扩展运算符
使用扩展运算符可以实现部分对象的深复制,若对象中有数组或其他引用类型,则扩展运算符不能实现深复制。
成功案例:
let obj1 = {
name: "rain",
age: 18
}
let obj2 = { ...obj1 }
obj2.name = "snow"
console.log(obj1)// {name:'rain',age:18}
console.log(obj2)// {name:'snow',age:18}
失败案例:
let obj1 = {
name: "rain",
arr: [1, 2, 3]
}
let obj2 = { ...obj1 }
obj2.arr[2] = 0
console.log(obj1)// {name:'rain',arr:[1,2,0]}
console.log(obj2)// {name:'rain',arr:[1,2,0]}
二、使用Object.assign()
使用
Object.assign()
方法和使用扩展运算符,出现的错误一样。
成功案例:
let obj1 = {
name: "rain",
age: 18
}
let obj2 = {}
Object.assign(obj2, obj1)
obj2.age = 20
console.log(obj1)// { name: 'rain', age: 18 }
console.log(obj2)// { name: 'rain', age: 20 }
失败案例:
let obj1 = {
name: "rain",
arr: [1, 2, 3]
}
let obj2 = {}
Object.assign(obj2, obj1)
obj2.arr[2] = 0
console.log(obj1)// { name: 'rain', arr: [ 1, 2, 0 ] }
console.log(obj2)// { name: 'rain', arr: [ 1, 2, 0 ] }
三、使用JSON.parse(JSON.stringify())
方法
可以满足大部分的情况,但还是会存在问题,当属性的值为
undefined
时,会出现属性遗失。当属性为方法function时此方法也不能使用。
成功案例:
let obj1 = {
name: "rain",
arr: [1, 2, 3]
}
let obj2 = JSON.parse(JSON.stringify(obj1))
obj2.arr[2] = 0
console.log(obj1)// { name: 'rain', arr: [ 1, 2, 3 ] }
console.log(obj2)// { name: 'rain', arr: [ 1, 2, 0 ] }
失败案例:
let obj1 = {
name: "rain",
arr: [1, 2, 3],
age: undefined
}
let obj2 = JSON.parse(JSON.stringify(obj1))
obj2.arr[2] = 0
console.log(obj1)// { name: 'rain', arr: [ 1, 2, 3 ], age: undefined }
console.log(obj2)// { name: 'rain', arr: [ 1, 2, 0 ] }
// 会发现obj2没有age属性
四、使用组件immutable
五、手写标准的深拷贝
// 手写标准的深拷贝 => 引用数据类型(数组,对象)
function deepClone(source) {
// [] => Array(基类) {}=> Object
const targetObj = source.constructor === Array ? [] : {};
for (let keys in source) {
if (source.hasOwnProperty(keys)) {
// 判断是否为引用数据类型
if (source[keys] && typeof source[keys] === "object") {
// 递归
targetObj[keys] = deepClone(source[keys]);
} else {
// 基本数据类型,直接赋值
targetObj[keys] = source[keys];
}
}
}
return targetObj;
}