JS中保护对象
js中保护对象:防止对对象中的属性值或者属性结构进行随意篡改(因为js中对象,毫无自保能力,可随时修改属性值,可随时添加、删除属性,可随时遍历所有的属性值)
如何保护:
1、保护属性:
ES5中将每个对象的属性,变成了一个缩微的小对象,每个缩微的小对象又包含四个特性:
其中configurable一旦修改为false,不可逆。所以,修改两个开关时,都会伴随configurable:false作为双保险。
获取一个属性的缩微小对象:
var eidObj=Object.getOwnPropertyDescriptor(
eric,"eid"
);
修改一个开关:
Object.defineProperty(eric,"eid",{
writable:false,
//防止再次打开writable开关
configurable:false
});
修改多个开关:
Object.defineProperties(eric,{
eid:{writable:false,configurable:false},
ename:{configurable:false},
salary:{enumerable:false,configruable:false}
});
使用开关自定义规则保护属性值的范围:
使用访问器属性:不实际存储属性值,仅提供对另一个数据属性的保护——保镖
前提:现有一个隐姓埋名的半隐藏数据属性,实际存储属性值
只能用defineProperties为对象添加访问器属性
var eric={eid:1001,ename:"埃里克",_age:24};
Object.defineProperties(eric,{
_age:{
enumerable:false,
configurable:false
},
//2.给_age请保镖age:
age:{
get:function () {
console.log("自动调用了age的get()");
return this._age;
},
//另一个保镖,专门负责修改原始属性值
set:function (value) {
console.log(`自动调用age的set(${value})`);
//value可接住要赋的新值
//如果新值>=18且<=65
if (value >= 18 && value <= 65) {
this._age = value;
} else {//如果验证不通过,就报错
throw Error(`年龄必须介于18~65之间`)
}
},
//让保镖age替_age抛头露面
enumerable:true,
configurable:false
}
});
//访问器属性用法和普通属性完全一样
//但试图获取属性值时,会自动调用get方法
//员工但age必须介于18~65之间
console.log(eric.age);
//试图修改属性值时,会自动调用set,并将新值先交给set的value参数验证
eric.age++;
console.log(eric.age);
eric.age=-2;//报错
2、保护结构:防止对对象的结构进行篡改,比如:添加新属性,删除现有的属性
有3个级别
一、防拓展:禁止给对象添加新属性
Object.preventExtensions(eric)
防止对eric的一切扩展
二、密封:在兼具防扩展的基础上,进一步防止删除现有属性
Object.seal(eric)
将eric密封起来
强调:属性值,依然可以修改。
seal原理:自动将所有属性的configurable为false
三、冻结:在密封基础上,进一步禁止修改属性值
何时:今后凡是共用的对象的属性值,不能随便更改
如何:Object.freeze(eric)
原理:自动将所有属性的writable:false
这三个级别只能选其一使用,不能同时使用多个