Object.freeze(obj)可以冻结一个对象,该对象的属性不能再被修改增添,响应系统无法追踪它的变化
当有一个数组或者对象,里面的内容一定不发生改变,那么就可以在data、vuex里冻结它,这样性能可以大大提高
<p v-for="item in list">{{ item.value }}</p>
new Vue({
data: {
// vue不会对list里的object做getter、setter绑定
list: Object.freeze([
{ value: 1 },
{ value: 2 }
])
},
created () {
// 界面不会有响应
this.list[0].value = 100;
// 下面两种做法,界面都会响应
this.list = [
{ value: 100 },
{ value: 200 }
];
this.list = Object.freeze([
{ value: 100 },
{ value: 200 }
]);
}
})
从上面的例子可以看出object.freeze()是浅冻结,和浅拷贝类型,只会冻结基本数据类型的对象属性,对于复杂数据类型的属性,其值依然会发生改变。
小栗子:
obj1 = {
internal: {}
};
Object.freeze(obj1);
obj1.internal.a = 'aValue';
obj1.internal.a // 'aValue'
那么要怎样实现深冻结呢?递归冻结
// 深冻结函数.
function deepFreeze(obj) {
// 取回定义在obj上的属性名
var propNames = Object.getOwnPropertyNames(obj);
// 在冻结自身之前冻结属性
propNames.forEach(function(name) {
var prop = obj[name];
// 如果prop是个对象,冻结它
if (typeof prop == 'object' && prop !== null)
deepFreeze(prop);
});
// 冻结自身(no-op if already frozen)
return Object.freeze(obj);
}
obj2 = {
internal: {}
};
deepFreeze(obj2);
obj2.internal.a = 'anotherValue';
obj2.internal.a; // undefined