问题: 旧js中,对象自己毫无自保能力!
解决: ES5中提供了一套保护对象自身的机制。
1.保护属性:
ES5中,对象中每个属性,不再只是一个简单的值。底层已经变成了一个缩微的小对象。
2.如何修改开关:
2.1只修改一个属性的开关:
//定义 属性
Object.defineProperty(对象名,"属性名",{
开关:true或false,
...:...
})
2.1.1强调:
今后,只要修改writable和enumerable两个开关时,都要同时修改configurable:false,阻止别人的程序重新打开我们关闭的开关。(configurable:false,不可逆)
2.1.2问题:
Object.defineProperty() 一句话只能保护一个属性。如果对象中有很多属性都需要保护,则代码会很繁琐
2.2Object.defineProperties可以一次保护多个属性:
Object.defineProperties(对象名,{
属性名1:{
开关名: true或false,
... : ...
},
属性名2:{
开关名: true或false,
... : ...
},
})
2.2.1问题: 如果想使用灵活的自定义规则保护属性值时,三个开关都不适用了!
2.2.2解决:
今后,只要使用灵活的自定义规则保护属性值时,都用访问器属性
2.2.3什么是:
自己不保存属性值,只提供对另一个数据属性的保护。——保镖
3.如何定义访问器属性: 2步
3.1定义小黑屋属性,转移原对象中原属性的值
Object.defineProperty(原对象,"小黑屋",{
value:原对象.要保护的属性,
writable:true,
enumerable:false, //小黑屋不能轻易被人发现
configurable:false //小黑屋不可删除
})
3.2定义访问器属性替身+2保镖
Object.defineProperty(原对象,"要保护的原属性名",{
get:function(){
//this->访问器属性eage所在的当前对象->eric
return this.小黑屋;
},
set:function(value){
if(判断条件){
this.小黑屋=value;
}else{
throw Error("自定义错误提示");//复习第一阶段try catch异常处理
}
},
//访问器属性自己不存值,只提供保护,所以没有value属性
//正是因为writable不好用,我们才被迫用访问器属性代替writable,所以用了get/set,就不用writable。
//因为替身必须替真实属性抛头露面,所以,必须可以被for in发现
enumerable:true,
//因为替身不能随意删除,所以
configurable:false
})
3.3外界如何使用访问器属性: 和使用对象的普通属性完全一样!
3.3.1取值: 对象.属性名
底层: 自动调用访问器属性的get()
3. 3.2修改: 对象.属性名=新值
底层: 自动调用访问器属性的set(),将新值传给()中的value形参。