09-保护属性

140 阅读2分钟

问题: 旧js中,对象自己毫无自保能力!

解决: ES5中提供了一套保护对象自身的机制。

1.保护属性:

ES5中,对象中每个属性,不再只是一个简单的值。底层已经变成了一个缩微的小对象。

保护属性1.jpg

保护属性7.jpg

2.如何修改开关:

2.1只修改一个属性的开关:

		//定义  属性
Object.defineProperty(对象名,"属性名",{
	开关:truefalse,
	...:...
})

保护属性3.jpg

2.1.1强调:

今后,只要修改writable和enumerable两个开关时,都要同时修改configurable:false,阻止别人的程序重新打开我们关闭的开关。(configurable:false,不可逆)

保护属性4.jpg

保护属性5.jpg

2.1.2问题:

Object.defineProperty() 一句话只能保护一个属性。如果对象中有很多属性都需要保护,则代码会很繁琐

2.2Object.defineProperties可以一次保护多个属性:

Object.defineProperties(对象名,{
	属性名1:{
		开关名: truefalse, 
		... : ...
	},
	属性名2:{
		开关名: truefalse, 
		... : ...
	},
})

保护属性5.jpg

2.2.1问题: 如果想使用灵活的自定义规则保护属性值时,三个开关都不适用了!

访问器属性1.jpg

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
    })

访问器属性2.jpg

访问器.png

3.3外界如何使用访问器属性: 和使用对象的普通属性完全一样!

3.3.1取值: 对象.属性名

底层: 自动调用访问器属性的get()

3. 3.2修改: 对象.属性名=新值

底层: 自动调用访问器属性的set(),将新值传给()中的value形参。

访问器属性3.jpg