写点什么

JavaScript 进阶(二)下下之深浅拷贝

用户头像
Augus
关注
发布于: 3 小时前
JavaScript 进阶(二)下下之深浅拷贝

### 深浅拷贝

let a = {
age : 1
}
let b = a
a.age = 2
console.log(b.age) // 2
复制代码


  • 从上述例⼦中我们可以发现,如果给⼀个变量赋值⼀个对象,那么两者的值会是同⼀个引⽤,其中⼀⽅改变,另⼀⽅也会相应改变。

  • 通常在开发中我们不希望出现这样的问题,我们可以使⽤浅拷⻉来解决这个问题

浅拷⻉

⾸先可以通过 Object.assign 来解决这个问题

let a = {
age: 1
}
let b = Object.assign({}, a)
a.age = 2
console.log(b.age) // 1
复制代码


当然我们也可以通过展开运算符 (…)来解决

let a = {
age: 1
}
let b = {...a}
a.age = 2
console.log(b.age) // 1
复制代码


通常浅拷⻉就能解决⼤部分问题了,但是当我们遇到如下情况就需要使⽤到深拷⻉了

let a = {
age: 1,
jobs: {
first: 'FE'
}
}
let b = {...a}
a.jobs.first = 'native'
console.log(b.jobs.first) // native
复制代码


浅拷⻉只解决了第⼀层的问题,如果接下去的值中还有对象的话,那么就⼜回到刚开始的话题了,两者享有相同的引⽤。要解决这个问题,我们需要引⼊深拷贝

深拷贝

这个问题通常可以通过 JSON.parse(JSON.stringify(object))来解决

let a = {
age: 1,
jobs: {
first: 'FE'
}
}
let b = JSON.parse(JSON.stringify(a))
a.jobs.first = 'native'
console.log(b.jobs.first) // FE
复制代码


但是该⽅法也是有局限性的:

  • 会忽略 undefined

  • 不能序列化函数

  • 不能解决循环引⽤的对象

let obj = {
a: 1,
b: {
c: 2,
d: 3,
},
}
obj.c = obj.b
obj.e = obj.a
obj.b.c = obj.c
obj.b.d = obj.b
obj.b.e = obj.b.c
let newObj = JSON.parse(JSON.stringify(obj))
console.log(newObj)
复制代码


如果你有这么⼀个循环引⽤对象,你会发现你不能通过该⽅法深拷⻉

  • 在遇到函数或者 undefined 的时候,该对象也不能正常的序列化

let a = {
age: undefined,
jobs: function() {},
name: 'poetries'
}
let b = JSON.parse(JSON.stringify(a))
console.log(b) // {name: "poetries"}
复制代码


你会发现在上述情况中,该⽅法会忽略掉函数和`undefined。

  • 但是在通常情况下,复杂数据都是可以序列化的,所以这个函数可以解决⼤部分问题,并且该函数是内置函数中处理深拷⻉性能最快的。当然如果你的数据中含有以上三种情况下,可以使⽤lodash 的深拷⻉函数。


END~~~

用户头像

Augus

关注

爱瞎搞的软件开发工程师 2021.06.10 加入

某摸鱼集团

评论

发布
暂无评论
JavaScript 进阶(二)下下之深浅拷贝