项目中遇到过的问题
前提
1、在store中存在这样一个对象,我们来看下它的结构:
state: {
siteInfo: {
classes: []
}
}
2、在页面初始化阶段,进行赋值:
data() {
return {
classes: this.$store.state.siteInfo.classes
}
}
1、这里有一个问题,当我们改变data中classes的值时会发生什么呢?
很简单,store中的classes也会跟着改变。
这就是我们所说的浅拷贝
浅拷贝是对对象的引用地址进行拷贝,并没有开辟新的栈,也就是拷贝后,两个对象指向同一个地址,修改其中一个对象的属性,另一个对象的属性也会改变。
我是分割线-----------------------------------------------------------------💯
2、这里又有一个问题,我们怎么做可以在改变classes值的时候保证store中classes的值依然是初始值呢?
先贴代码
Object.assign([], this.$store.state.siteInfo.classes);
Very Easy,这样就可以了。
我们可以看到,在实现这个需求的时候用到一个方法:
Object.assign(target, …sources)
- target:目标对象
- sources:源对象。
该方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。(MDN)
这样就可以了吗?
是的,只是实现这样的需要已经可以了。
我是分割线-----------------------------------------------------------------💯
3、不过这里还有一个问题,我们来看一个demo
let Obj1 = {uesr: {name: '1m'}}
let Obj2 = Object.assign({}, Obj1);
Obj2.uesr = '01';
console.log(Obj1) // {uesr: {name: '1m'}}
console.log(Obj2) // {uesr: '01'}
没问题,这个结果是我们预期的。
然后我们再这样做:
Obj2.uesr.name = `whit's your name ?`;
console.log(Obj1) // {uesr: {name: 'whit's your name ?'}}
console.log(Obj2) // {uesr: {name: 'whit's your name ?'}}
嗯?不对呀,怎么改变obj2,obj1也跟着变了。
我们观察一下,两次修改有什么不一样。
结论:
Object.assign()方法只能对对象的第一层进行深拷贝。slice、concat等方法同样遵循这条。
那么遇到这种情况怎么处理呢。
最简单的方法就是通过JSON.parse(JSON.stringify(obj))
这样就实现了一个彻底的深拷贝。
我是分割线-----------------------------------------------------------------💯
最后,我们来总结一下深拷贝
深拷贝是开启一个新的栈,两个对象对应两个不同的引用地址,修改一个对象的属性,不会改变另一个对象的属性。
我是底部
一些开发过程中的经验总结,如果对你有帮助,那真是一件很棒的事,如果内容有什么问题或建议,欢迎在下方留言。😀 😀 😀