zoukankan      html  css  js  c++  java
  • 探秘隐藏在对象中的get和set方法

    不知道大家有没有注意过对象中的一些通用方法,例如所有所有的对象都有 toString、constructor 等等一些方法。

     

    当然如果要仔细看的话,大家可以:

     

     var a = {};
        console.log(a);

     

    img

     

    我们可以清晰的看到他有很多的内置方法。当然,也可以看到最下面有两个比较怪的方法 get 和 set ,只要是对象就可以找到这两个方法,但是究竟怎么使用这两个方法呢?

     

    我自己研究了半天,发现可以这样使用,就拿最简单的对象 json 来举例。

     

     
     var Json = {
            set Leo(value){
                console.log(value)
            }
         };
        Json.Leo = 'liyou' //'liyou' 
     

     

     

    使用起来你会发现非常的怪异, 这个东西看起来像个函数,但是又必需赋值才能用。我们理解起来大概就是,只要一赋值,这个属性就被从新赋予新的东西,而「这个」则是执行了这个函数。

     

    那么,到底他是不是函数呢?我们来继续探索一下这个 set 。

     
     
      typeof Json.Leo //undefined 
        Json.Leo() //Error:Json.Leo is not a function 
     

     

     

    也就是说,「这个」东西不是作为他的私有属性存在,而「这个」也不是函数。

     

    继续实验的话,会发现「这个」东西只可以传一个参数。

     

     var Json = {
     ​
     •       set Leo(value,nextValue){ //Uncaught SyntaxError: Setter must have exactly one formal parameter.

     

     

     

     

    代码提示一个只允许使用一个参数,也是说他只支持一个参数。当然,如果我们想传很多的话,似乎也只能通过 json 。

     

     var Json = {
            set Leo(...val){ //Uncaught SyntaxError: Setter function argument must not be a rest parameter
                console.log(val)
            }
         };
        Json.Leo = 'liyou' 
     ​
     ​
     ​
     不支持 ES6 的不定数组参,但是支持 arguments 。
     ​
     ​
     ​
     var Json = {
            set Leo(val){
                console.log(arguments[0])
            }
         };
        Json.Leo = 'liyou' //'liyou';

     

     

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

     

    例如:

     
     var Json = {
            set Leo(val){
                console.log(arguments[0])
            },
            get Leo(){
                console.log('liyou')
            } 
         };
        Json.Leo //'liyou';
     

     

     

    当然我们可以看出来,如果赋值就会走 set ,如果没有赋值就会走 get 。

     

    值得一提的是, get 方法是不允许有参数的,一旦里面放入一个参数,就会直接报错。

     

    虽然可以顺利使 get 方法,但是如果我们想要找到「这个」东西到底,结果是我们依然找不到他。

     

     Json.Leo //'liyou'
    typeof Json.Leo // undefined

     

     

    简而言之,一个内置的函数体可以使用,但是不能当作正常的一个私有属性来判断其数据类型。

     

    那么,如果这个函数体碰上了真正的私有属性会变称什么样呢?

     

    例如:

     

     var Json = {
     ​
     •      get Leo(){
     •         return 10;
     •      },
     •     Leo:20
     ​
        };
        console.log(Json.Leo)? 

     

     

    答案是 undefined 。其实也不难怪,因为似乎 js 也不知道你拿的是内置函数体还是私有属性,而且似乎本来性质也不一样,所以到头来也只能给你一个 undefined 。

     

    当然这里面的 this 还是指向对象本身的。

     

    例如:

     
     
     var Json = {
     ​
     •      get Leo(){
     •        return this
     •      }
     ​
        };
        
        Json.b = Json.Leo//
     

     

     

    这个时候 json 下面就有无穷无尽的 b ,就像 window 下面有无穷的 window 一样。

     

    值得一提的是,「这个」东西只能手动的在写对象的时候写到里面,而不能通过赋值去给予。

     

    例如:

     

      var a = {};
        a['set Leo'] = function(){}//

     

     

    这里面的 set 和上文的 set 不是一个东西。

     

    当然 json 中的 get/set 也可以循环使用。

     

    例如:

     
     
     var Json = {
     ​
     get Leo(){
     ​
     return {
     ​
     get isTeacher(){
     ​
     console.log('liyou')
     ​
     }
     ​
     }
     ​
     }
     ​
     ​
     ​
     }
     ​
     ​
     ​
     Json.Leo.isTeacher //'liyou'
     

     

     

    「这个」东西不能在一般的函数中使用。

     

    比如,function show(){set Leo(){}} // 报错。虽然 new show() 里面有这个内置函数,但是还是不能使用。

     

    但是却可以在 ES6 中的 class 对象中使用。

     

    例如:

     class Leo {
     ​
      constructor() {
     ​
      }
     ​
      get show() {
     ​
       return 'liyou';
     ​
      }
     ​
      set show(value) {
     ​
       console.log('liyou: '+value);
     ​
      }
     ​
     }
     ​
     let inst = new Leo();
     ​
     inst.show = 123;
     ​
     // liyou: 123
     ​
     inst.show
     ​
     // 'liyou'

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

    总结

    对了,小编为大家准备了一套2020最新的web前端资料,需要点击下方链接获取方式

    学习前端,你掌握这些。二线也能轻松拿8K以上

     

  • 相关阅读:
    【PAT】1020. Tree Traversals (25)
    Pongo建立信号基站-实际上还是考中位数
    从此不再惧怕URI编码:JavaScript及C# URI编码详解
    WebBrowser与IE的关系,如何设置WebBrowser工作在IE9模式下?
    命令行下开启与关闭windows防火墙关端口(转)
    MySql数据库批量备份命令
    C#检查文件是否被占用
    C#使用Gzip解压缩完整读取网页内容
    [转]免费电话网专用免费平台
    libQt5Core.so: undefined reference to `dlclose@GLIBC_2.4'
  • 原文地址:https://www.cnblogs.com/coderhf/p/13224470.html
Copyright © 2011-2022 走看看