深拷贝 浅拷贝
浅拷贝
?先可以通过 Object.assign 来解决这个问题,很多?认为这个函数是?来 深拷?的。其实并不是, 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
·会忽略 symbol
·不能序列化函数
·不能解决循环引?的对象
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)
简单来说深拷贝就是当遇到值是对象类型的时候就再运行一遍复制:
function deepCopy (obj) {
var result;
//引用类型分数组和对象分别递归
if (Object.prototype.toString.call(obj) == '[object Array]') {
result = []
for (i = 0; i < obj.length; i++) {
result[i] = deepCopy(obj[i])
}
} else if (Object.prototype.toString.call(obj) == '[object Object]') {
result = {}
for (var attr in obj) {
result[attr] = deepCopy(obj[attr])
}
}
//值类型直接返回
else {
return obj
}
return result
}