浅冻结:
Object.freeze冻结对象的时候,只会冻结里面的基本数据类型,并且是冻结的是值,对于里面的对象是无法冻结的,还可以进行修改,是因为地址还有引用。这也叫做浅冻结
深冻结:
冻结的对象不管里面有多少层嵌套的复杂数据类型,通过递归,全部冻结
冻结数组:也是冻结数组的最外层,里面嵌套的依然冻结不了
vue中冻结:
在要进入data前在拿到接口数据就冻结,可以做深度冻结。
下面是一个vue的组件,直接复制,运行就能看到
<template>
<div class="enter-box">
<input type="text" v-model="obj.value" style="border:1px solid #333">
<el-input v-model="obj.value" placeholder="请输入内容"></el-input>
<el-button @click="addFn" type="primary" size="small">添加</el-button>
<ul>
<li v-for="(item,i) in obj" :key="i">{{item}}</li>
</ul>
<ul>
<li v-for="(item,index) in obj.msg" :key="index">{{item}}</li>
</ul>
</div>
</template>
<script>
var deepFreeze =function (obj) {
var allProps = Object.getOwnPropertyNames(obj);
allProps.forEach(item => {
if (typeof obj[item] === 'object') {
deepFreeze(obj[item])
}
})
return Object.freeze(obj);
}
export default {
name: "enter-box",
watch:{
obj:{
deep:true,
handler(val){
console.log(val,"我是obj");
},
// immediate:true
}
},
data () {
return {
obj:{},
// 浅冻结
// obj: Object.freeze({
// value:'喜好',
// msg:{
// name:'zs',
// age:18,
// like:'eat'
// }
// }),
// 深冻结
// obj:deepFreeze({
// value:'喜好',
// msg:{
// name:'zs',
// age:18,
// like:'eat'
// }
// })
}
},
methods:{
addFn(){
// this.obj.sex = '男';
this.obj.msg.from = '北京';
// this.$set(this.obj,'sex','男')
// this.$set(this.obj.msg,'from','北京');
console.log(this.obj); //如果是浅冻结,此时打印obj,还会把from的属性添加到obj.msg中
// 深冻结后就会报错了,提示不能扩展。所以我们想冻结一个嵌套的对象,要去做深冻结,否则就可能会在点击事件什么了,无意去赋值
},
deepFreeze(obj) {
var allProps = Object.getOwnPropertyNames(obj);
allProps.forEach(item => {
if (typeof obj[item] === 'object') {
deepFreeze(obj[item])
}
})
return Object.freeze(obj);
}
},
created(){
// this.obj.msg.age=30;
// this.obj.value = '试试'
//----------------------------------------------------------------------------
// 在created中拿到接口数据直接冻结
var getData = {
value:'喜好',
msg:{
name:'zs',
age:18,
like:'eat'
}
};
Object.freeze(getData) //浅冻结,无法阻止在mounted中执行添加修改obj中对msg对象添加"form"属性
// this.deepFreeze(getData); //深冻结,就刀枪不入了
this.obj = getData;
// this.obj.value='哈哈'
},
mounted(){
// this.addFn();
}
}
</script>
<style lang="scss" scoped>
.enter-box{
padding: 150px;
font-size: 50px;
.el-button{
margin: 50px 0 20px;
}
ul{
padding: 30px 0;
border-bottom: 1px solid #999;
}
}
</style>