深浅拷贝
js
let a = {
age: 1
}
let b = a
a.age = 2
console.log(b.age) // 2从上,若给一变量赋值一对象,两者值会是同一个引用,其一修改另一也会改变。
浅拷贝
首先可通过Object.assign来解决
js
let a = {
age: 1
}
let b = Object.assign({}, a)
a.age = 2
console.log(b.age) // 1还可以通过展开运算符来解决
js
let a = {
age: 1
}
let b = {...a}
a.age = 2
console.log(b.age) // 1通常浅拷贝就能解决大部分问题了,但是当我们遇到如下情况需要深拷贝:
js
let a = {
age: 1,
jobs: {
first: 'FE'
}
}
let b = {...a}
a.jobs.first = 'VUE'
console.log(b.jobs.first)浅拷贝只解决第一层的问题,如果接下去的值中还有对象,那么又回到之前的问题,两者共享引用,解决这个问题就引入了深拷贝
深拷贝
一般地,可以通过 JSON.parse(JSON.stringify(obj))来解决
但该方法有局限性:
- 会忽略 undefined
- 不能序列化函数
- 不能解决循环引用的对象
如果你所需拷贝的对象含有内置类型并且不包含函数,可以使用 MessageChannel
js
function deepClone(obj) {
return new Promise(resolve => {
const {port1, port2} = new MessageChannel()
port2.onmessage = ev => resolve(ev.data)
port1.postMessage(obj)
})
}
var obj = {
a: 1,
b: {
c: b
}
}
// 注意,该方法是异步的,可以处理undefined和循环引用对象
const clone = await deepClone(obj)