深浅拷贝
开发中我们经常需要复制一个对象, 如果直接用赋值, 会出现一下问题
js
const Obj = {
Name: "柒月",
Age: 18
}
// 直接使用赋值
const O = Obj
// 复制成功了
console.log(O)
// {Name: "柒月", Age: 18}
// 这个时候我们修改一下对象O
O.Name = "洱海"
console.log(O)
// {Name: "洱海", Age: 18}
console.log(Obj)
// {Name: "洱海", Age: 18}
发现了么, 我修改对象O
, 会导致对象Obj
一起被修改, 这是因为, 虽然复制成功了, 实际上是将Obj
对象的引用复制给了变量O
, 因此, O
和Obj
指向内存中的同一个对象, 修改O
会导致Obj
也发生变化
这个时候就要使用拷贝了, 拷贝有浅拷贝和深拷贝
浅拷贝和深拷贝只针对引用类型
浅拷贝
拷贝的是地址
常见的方法:
- 拷贝对象
Object.assgin()
{...Obj}
- 拷贝数组
Array.prototype.concat()
[...arr]
js
const Obj = {
Name: "柒月",
Age: 18
}
// 浅拷贝-拷贝对象
// 方法1
// const O = {}
// Object.assign(O, Obj)
// 方法2
const O = { ...Obj }
console.log(O)
// {Name: "柒月", Age: 18}
// 这个时候我们修改一下对象O
O.Name = "洱海"
console.log(O)
// {Name: "洱海", Age: 18}
console.log(Obj)
// {Name: "柒月", Age: 18}
看起来似乎解决问题了, 但是还是有问题的:
js
const Obj = {
Name: "柒月",
Age: 18,
Two: {
A: "B"
}
}
const O = { ...Obj }
// 这个时候我们修改一下对象O
O.Name = "洱海"
O.Two.A = "洱海"
console.log(O)
// {Name: "洱海", Age: 18, Two: {A: "洱海}}
console.log(Obj)
// {Name: "柒月", Age: 18, Two: {A: "洱海}}
发现了么, 修改对象O
里的对象Two
里面的属性还是会影响对象Obj
(绕绕的)
浅拷贝它确实创建了一个新的对象, 但是这个新对象中的属性如果是基本类型则直接复制值
如果是对象(Two
), 则复制的是对象的引用
这就是所谓的浅拷贝
简单来说, 单层对象没问题, 如果是多层对象就有问题了
深拷贝
拷贝的是对象
常见的方法:
- 通过递归实现深拷贝
- 通过
JSON.stringify()
实现
通过递归实现
js
// 我在这里写的递归是通用的, 你完全可以直接复制粘贴走
// 这个代码块就当做使用说明了
const DeepCopy = (OldObj) => {
let NewObj = {}
for (let K in OldObj) {
if (OldObj[K] instanceof Array) {
// 处理数组
NewObj[K] = []
DeepCopy(OldObj[K])
} else if (OldObj[K] instanceof Object) {
// 处理对象
NewObj[K] = {}
DeepCopy(OldObj[K])
} else {
// 处理正常
NewObj[K] = OldObj[K]
}
}
return NewObj
}
const Obj = {
Name: "柒月",
Age: 18,
A: ["柒", "月"],
O: {
A: "B"
}
}
const O = DeepCopy(Obj)
O.Name = "洱海"
O.A[0] = "洱"
O.A[1] = "海"
O.O.A = "C"
console.log(O)
// { Name: "洱海", Age: 18, A: [ "洱", "海" ], O: { A: "C" } }
console.log(Obj)
// { Name: "柒月", Age: 18, A: [ "柒", "月" ], O: { A: "B" } }
通过JSON实现
这个方法可谓是十分简单
经常洗钱的朋友应该会觉得亲切
js
const Obj = {
Name: "柒月",
Age: 18,
A: ["柒", "月"],
O: {
A: "B"
}
}
// 将对象转换为字符串在转换为对象
// 转回为字符串的时候就已经和原版的对象没有任何关系了
const O = JSON.parse(JSON.stringify(Obj))
O.Name = "洱海"
O.A[0] = "洱"
O.A[1] = "海"
O.O.A = "C"
console.log(O)
// { Name: "洱海", Age: 18, A: [ "洱", "海" ], O: { A: "C" } }
console.log(Obj)
// { Name: "柒月", Age: 18, A: [ "柒", "月" ], O: { A: "B" } }