zoukankan      html  css  js  c++  java
  • 关于 Object.defineProperty()

    这个东东其实没那么难,先来看看它的功能和使用方式:

    Object.defineProperty(obj, prop, descriptor)

    • obj: 需要定义属性的对象。

    • prop: 需定义或修改的属性的名字。

    • descriptor: 将被定义或修改的属性的描述符。

    • 返回值:返回传入函数的对象,即第一个参数obj。

    三个参数都是必填的

    关于描述符 descriptor

    对象里目前存在的属性描述符有两种主要形式:数据描述符和存取描述符。数据描述符是一个拥有可写或不可写值的属性。存取描述符是由一对 getter-setter 函数功能来描述的属性。描述符必须是两种形式之一;不能同时是两者。

    数据描述符和存取描述符均具有以下可选键值:

    • configurable
      当且仅当该属性的 configurable 为 true 时,该属性描述符才能够被改变,也能够被删除。默认为 false。

    • enumerable
      当且仅当该属性的 enumerable 为 true 时,该属性才能够出现在对象的枚举属性中。默认为 false。

    数据描述符同时具有以下可选键值:

    • value
      该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined。

    • writable
      当且仅当该属性的 writable 为 true 时,该属性才能被赋值运算符改变。默认为 false。

    存取描述符同时具有以下可选键值:

    • get
      一个给属性提供 getter 的方法,如果没有 getter 则为 undefined。该方法返回值被用作属性值。默认为 undefined。

    • set
      一个给属性提供 setter 的方法,如果没有 setter 则为 undefined。该方法将接受唯一参数,并将该参数的新值分配给该属性。默认为 undefined。

    具体示例:

    var o = {};
    // o.mm = 'lyt'
    Object.defineProperty(o, 'mm', {
        value: 'lyt',
        configurable: true,
        enumerable: true,
        writable: true
    });
    // 这种写法和上面的是一个意思。
    

    如果configurable为默认值false,那么再去修改除writeable以外的属性都会抛出异常,也就是说这个属性是个总开关。

    var o = {};
    
    Object.defineProperty(o, 'mm', {
        value: 'lyt'
    });
    
    Object.defineProperty(o, 'mm', {  // 报错
        configurable: true
    });
    
    

    如果enumerable为默认值false,则该属性不能被for-in循环所遍历。

    var o = {};
    
    Object.defineProperty(o, 'mm', {
        value: 'Tina',
        enumerable: true
    });
    
    Object.defineProperty(o, 'name', {
        value: 'lyt'
    });
    
    for(var key in o){
        console.log(o[key]); // Tina
    }
    

    如果writable为默认值false,那么属性将不可写,只能读。

    var o = {};
    
    Object.defineProperty(o, 'mm', {
        value: 'Tina'
    });
    
    o.mm = 'lmm';
    
    console.log(o.mm)  // Tina
    

    关于 get 和 set 函数

    通过Object.defineProperty()来设置存储描述符的时候,当对对应的数据进行读取操作的时候会触发get函数,对数据进行写入操作的时候会触发set函数,下面这个例子就会让你搞清楚它们的作用:

    var o = {};
    
    Object.defineProperty(o, 'mm', {
        get:function (){
            console.log('卢雨婷大美妞取了我的值');
            return 'Tina'  // 返回值即使读取的值
        },
        set:function (value){  // 这个参数的名字随便
            console.log(`我的值被卢小妞设置成了${value}`);
            // 这里使用this.mm = value赋值要注意,会形成递归。
        }
    });
    
    o.mm;
    o.mm = '白痴';
    

    至于取值和赋值的时候的行为,就随需求而定了。

    应用:MVVM框架的基本原理

    <div>
        <p>你好: <span id="name">111</span></p>
        <div id="intname">222</div>
    </div>
    <script>
        var userInfo = {};  // 模拟后台数据
        
        // 当对数据取值和赋值的时候对DOM进行相应的更新
        Object.defineProperty(userInfo,'name', { 
          get:function () {
            return document.getElementById('name').innerHTML;
          },
          set:function (value) {
            document.getElementById('name').innerHTML = value;
          }
        })
        
        Object.defineProperty(userInfo,'intname', {
          get:function () {
            return document.getElementById('intname').innerHTML;
          },
          set:function (value) {
            document.getElementById('intname').innerHTML = value;
          }
        })
        
        console.log(userInfo.name);
        
        userInfo.name = 'lyt';
        userInfo.intname = 'Tina';
        
        console.log(userInfo.name);
    </script>
    

    总结:以上,你没看错,就这么简单。

  • 相关阅读:
    HDU1548图论Dijkstra
    LINUX下sql常用命令
    Oracle DBLINK 简单使用
    自己常用百度搜索指令
    Element获取table中选中的行
    【Java】SpringBoot不扫描某个包
    Oracle创建Database link方法
    Oracle数据库中快照的使用
    spring.profiles.active和spring.profiles.include的使用与区别
    Spring Cloud Config 实现配置中心,看这一篇就够了
  • 原文地址:https://www.cnblogs.com/copperhaze/p/6240939.html
Copyright © 2011-2022 走看看