保护对象: 阻止程序对一个对象执行不合常理的修改
两个层面的保护
(1). 保护单个属性: 阻止对对象中某个属性执行不合常理的修改
(2). 保护对象结构: 阻止乱添加删除属性
1 保护单个属性
ES5对对象的属性进行了分类:命名属性和内部属性
(1)命名属性:所有可用.访问的属性
①数据属性:实际存储属性值的属性;
②访问器属性:自己不实际存储属性值,而是对数据属性提供保护的属性;
(2)内部属性:存在于对象内,但是不允许用.访问的属性
比如每个对象都有一个class属性,来标记当前对象被创建时的数据类型名,但是使用对象.class却是undefined
何保护数据属性①:专门的函数
其实我们看到的对象中的一个属性,已经不再仅仅是一个变量而已。对象中的每个属性,其实都是一个缩微的小对象,每个小对象中都包含一个属性值value和三个开关
使用专门的函数:
//修改单个属性
Object.defineProperty(对象,"属性名",{ writable: true/false, //读 enumerable:true/false, //遍历 configurable: true/false, //控制前面两个属性是否可修改(一旦写好无法外部改写) })
//修改多个属性
Object.defineProperties( 对象, {
属性名:{
开关:true/false,
... : ...,
},
属性名:{
开关:true/false,
... : ...,
}
} )
如何保护数据属性②:使用访问器属性保护
步骤:
1). 为对象添加一个半隐藏的新数据属性,负责实际保存属性值;
2). 为这个半隐藏的受保护的数据属性请保镖:get 和 set
var obj={ _age } //js能自动识别set和get Object.defineProperties(obj,{ _age:{ value:obj.eage, writable:true, enumerable:false, configurable:false } , //顶替_age的属性 //访问器属性只能在definePerty/defineproperties中添加 age:{ get(){ //通过访问器属性访问真实的属性值 return this._age; }, set(value){ //通过访问器属性修改真实的属性值 this._age=value; } } })
2 保护对象的结构
(1)禁止给对象强行添加新属性:Object.preventExtensions(对象);
(2)既禁止添加新属性,又禁止删除现有属性,但是属性值还是可以随便改:Object.seal(对象)
一般情况下,一个对象保护到密封级别就够了
(3)既不能添加删除属性,又不能修改任何属性值:Object.freeze(对象)
extensible=false;configurable=false;writable=false