把一个对象赋值给另外一个对象,赋的都是改对象栈中的地址(指针),而不是堆中的数据。两个对象的指针还是指向同一个存储空间,无论谁发生改变,都是改变存储空间中的值。因此两个对象是联动的互相影响的。
浅拷贝
要通过浅拷贝去解决这个问题。
浅拷贝的方法有:
ES5 concat()
const a1 = [1, 2];
const a2 = a1.concat();
a2[0] = 2;
a1
// [1, 2]
Object.assign
let a = {
age: 1
}
let b = Object.assign({}, a)
a.age = 2
console.log(b.age) // 1
ES6
通过扩展运算符 ...
const a1 = [1, 2];
// 写法一
const a2 = [...a1];
// 写法二
const [...a2] = a1;
但是浅拷贝只是解决了最外层的问题,多层就不适用(因为浅拷贝与原来不是一个空间,新空间里存放的多层对象或者数组,还是对原来存储空间的引用)
let a = {
age: 1,
jobs: {
first: 'FE'
}
}
let b = {...a}
a.jobs.first = 'native'
console.log(b.jobs.first) // 输出的是native 不再是原来的值
这时候就要用到深拷贝
深拷贝
JSON.parse(JSON.stringify(a))
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会自动忽略这个键值(就不能正常序列化)。
-
如果有循环引用会报错(JSON.stringify的时候就会报错)
Converting circular structure to JSON
--> starting at object with constructor 'Object'
--- property 'c' closes the circle
at JSON.stringify (<anonymous>)
at test.html:28 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)
网友评论