探秘隐藏在对象中的get和set方法

来源:互联网 发布:php周末培训班 编辑:程序博客网 时间:2024/05/22 17:13
 其实我不知道大家有没有注意过对象中的一些通用方法,例如所有所有的对象都有 toString、constructor等等一些方法。
      当然如果要仔细看的话 大家可以
      var a = {};

      console.log(a);


 我们可以清晰的看到他有很多的内置方法。当然也可以看到最下面有两个比较怪的方法get和set。只要是对象就可以找到这两个方法,但是究竟怎么使用这两个方法呢?
       自己研究了半天,发现可以这样使用,我们就拿最简单的对象JSON来举例。
       var Json = {
             set Lb(value){
                     console.log(value)
              }
       };
      Json.Lb = 'libo' //'libo'   
      当然使用起来你会发现非常的怪异。 这个东西看起来像个函数 但是又必需赋值才能用,我们理解起来的是只要一赋值这个属性就被从新赋予新的东西,而这个则是执行了这个函数。
      到底他是不是函数呢?我们来继续探索一下这个set.
      typeof Json.Lb //undefined 
      Json.Lb() //Error:Json.Lb is not a function 
      也就是说 这个东西不是作为他的私有属性存在而这个也不是函数。 
      继续实验的话,会发现这个东西只可以穿一个参数。
      var Json = {
             set Lb(value,nextValue){ //Uncaught SyntaxError: Setter must have exactly one formal parameter.
                     console.log(argument[0])
              }
       };
      Json.Lb = 'libo'

      提示一个只允许使用一个参数。也是说他只支持一个参数当然如果我们像传很多的话似乎也只能通过json。
       var Json = {
             set Lb(...val){ //Uncaught SyntaxError: Setter function argument must not be a rest parameter
                     console.log(val)
              }
       };
      Json.Lb = 'libo' 
      不支持 ES6的不定数组参。

      但是支持arguments.
      var Json = {
             set Lb(val){
                     console.log(arguments[0])
              }
       };
      Json.Lb = 'libo' //'libo';


    而get方法和他很接近使用起来就像一个私有的属性用起来一样。
    例如: 

    var Json = {
             set Lb(val){
                     console.log(arguments[0])
              },
             get Lb(){
                     console.log('libo')
             } 
       };
      Json.Lb //'libo';
      当然我们可以看出来 如果赋值就会走set,如果没有赋值就会走get。
      当然值得一提的就是get方法不允许有参数,一旦里面放入一个参数就会直接报错了。
      当然虽然虽然可以顺利使get方法但是如果我们找这个东西到底是啥的话,我们依然找不到。
      Json.Lb //'libo'
      typeof Json.Lb // undefined  
      
      说白了就是一个内置的函数体可以使用但是不能当作正常的一个私有属性来判断其数据类型。
      当然如果这个函数体碰上了 真正的私有属性会变称什么样呢?
      例如:

      var Json = {

           get Lb(){
                 return 10;
           },
          Lb:20

      };
      console.log(Json.Lb)? 



       答案最后是undefined,其实也不难怪,因为似乎js 也不知道你拿的内置函数体还是私有属性,而且似乎本来性质也不一样,所以到头来也只能给你一个undefined
       
       当然这里面的this 还是指向对象本身。例如  
       var Json = {

           get Lb(){
                return this
           }

      };
      
      Json.b = Json.Lb//
      这个时候json 下面就有无穷无尽的b ,就像window下面有无穷的window一样。
      值得一提的是这个东西只能手动去在写对象的时候去写里面,而不能通过赋值去给予
      例:
      var a = {};
      a['set Lb'] = function(){}//这里面的set 和上文的set 不是一个东西。



      当然json 中的get/set 也可以循环使用 例如
       var Json = {
get Lb(){
return {
get isTeacher(){
console.log('libo')
}
}
}


}


Json.Lb.isTeacher //'libo'
       

      这个东西不能在一般的函数中使用,例如:
      function show(){set Lb(){}} //报错 虽然new show()里面有这个内置函数 但是还是不能使用。

     但是可以在ES6中的class 对象中使用
     例如:
     class Lb {
  constructor() {
  }
  get show() {
    return 'libo';
  }
  set show(value) {
    console.log('libo: '+value);
  }
}


let inst = new Lb();


inst.show = 123;
// libo: 123


inst.show
// 'libo'

       当然class类本身也属于函数对象,所以函数对象中有这个get/set内置函数,就不奇怪了。