目录
在正式进入正文前,先说下const
const 定义的是常量,且不能再修改,但是它只能对简单类型的数据生效,对于复杂类型就无效了(const保存的是引用地址),如果想冻结对象的话,那就可以使用今天介绍的对象冻结。
vue2中的Object.defineProperty() 注:(数据劫持)就是劫持的对象的属性,而今天的猪脚就是和他对着干的
在实际开发中,我们会需要一个真正常量对象:这个对象一经初始化,就不能被添加属性,删除属性,修改属性。
Object.freeze()方法可以冻结一个对象。具体来说冻结指的是:
•不能向这个对象添加新的属性
•不能修改其已有属性的值
•不能删除已有属性
•以及不能修改该对象已有属性的可枚举性、可配置性、可写性。
注意:这个方法返回值是你传入对象,而不是创建一个被冻结的副本,也就是说它直接修改了入参。
Object.freeze(obj)
// obj要被冻结的对象。
// 返回值是被冻结的对象。
const constSettings = {
appName:"fan",
info: {p1:200,p2:300 }
};
Object.freeze(constSettings);
constSettings.appName = 1 ;
// 悄悄地无效
constSettings.other = "abc";
// 悄悄地无效
constSettings.info.p1 = 100;
// 生效了
console.info(constSettings)
// {appName:"fan",info:{p1:100,p2:300}
注意:
1.不需要额外定义一个常量来接收freeze()的返回值,写成
const obj = Object.freeze(constSettings)
。freeze()会直接修改入参。2.添加other属性,修改appName 这两个操作均没有显示地报错误,但也没有修改成功。
3.仍可以以修改属性的属性:
constSettings.info.p1 = 100;
原因是freeze()只能冻住一层。
只能冻结第一层,比如一个对象里面还有对象这种嵌套的形式,我们可以采用递归+Object.freeze()实现。
function deepFreeze(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);
}
const constSettings = {
appName:"a",
info: {p1:200,p2:300 }
};
deepFreeze(constSettings);
constSettings.appName = 1
// 悄悄地无效
constSettings.other = "abc"
// 悄悄地无效
constSettings.info.p1 = 100
// 也悄悄地无效
console.info(constSettings)