zoukankan      html  css  js  c++  java
  • 理解Object.defineProperty

    Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或在修改一个对象的现有属性,并返回这个对象(即第一个参数obj)

    语法:

    Object.defineProperty(obj , prop , descriptor)


    //
    obj:要在其上定义属性的对象 //prop:要定义或修改的属性的名称 //descriptor:将被定义或修改的属性描述符

     vue.js就是通过Object.defineProperty实现双向绑定

    给对象的属性添加特性描述,目前提供两种形式:数据描述和存取器描述

    数据描述

    当修改或定义对象的某个属性的时候,给这个属性添加一些特性

    value: 设置属性的值
    writable: 值是否可以重写。true | false
    enumerable: 目标属性是否可以被枚举。true | false
    configurable: 目标属性是否可以被删除或是否可以再次修改特性 true | false

    value:属性对应的值,可以是任意类型的值,默认为undefined

    let obj = {}
    //第一种情况:不设置value属性
    Object.defineProperty(obj,"newKey",{
    
    });
    console.log( obj.newKey );  //undefined
    ------------------------------
    //第二种情况:设置value属性
    Object.defineProperty(obj,"newKey",{
        value:"hello"
    });
    console.log( obj.newKey );  //hello

    writable:属性的值是否可以被重写,默认为false,设置为true可以被重写

        let Person = {};
        Object.defineProperty(Person,'city',{
            city:'伦敦'
            //writable默认为false,不能改变属性值
        })
        Person.city = '巴黎';
        console.log(Person.city);//undefined
       let Person = {};
        Object.defineProperty(Person,'city',{
            city:'伦敦',
            writable:true
        })
        Person.city = '巴黎';
        console.log(Person.city);//巴黎

    enumerable:此属性是否可以被枚举

    设置为true可以被枚举;设置为false,不能被枚举(默认false)

    var obj = {}
    //第一种情况:enumerable设置为false,不能被枚举。
    Object.defineProperty(obj,"newKey",{
        value:"hello",
        writable:false,
        enumerable:false
    });
    
    //枚举对象的属性
    for( var attr in obj ){
        console.log( attr );  
    }
    //第二种情况:enumerable设置为true,可以被枚举。
    Object.defineProperty(obj,"newKey",{
        value:"hello",
        writable:false,
        enumerable:true
    });
    
    //枚举对象的属性
    for( var attr in obj ){
        console.log( attr );  //newKey
    }

    configurable:是否可以删除目标属性或是否可以再次修改属性的特性

    设置true可以被删除或可以重新设置特性,false不能设置

    这个属性起到的作用

    1. 目标属性是否可以使用delete删除

    2. 目标属性是否可以再次设置特性

    //-----------------测试目标属性是否能被删除------------------------
    var obj = {}
    //第一种情况:configurable设置为false,不能被删除。
    Object.defineProperty(obj,"newKey",{
        value:"hello",
        writable:false,
        enumerable:false,
        configurable:false
    });
    //删除属性
    delete obj.newKey;
    console.log( obj.newKey ); //hello
    
    //第二种情况:configurable设置为true,可以被删除。
    Object.defineProperty(obj,"newKey",{
        value:"hello",
        writable:false,
        enumerable:false,
        configurable:true
    });
    //删除属性
    delete obj.newKey;
    console.log( obj.newKey ); //undefined
    //-----------------测试是否可以再次修改特性------------------------
    var obj = {}
    //第一种情况:configurable设置为false,不能再次修改特性。
    Object.defineProperty(obj,"newKey",{
        value:"hello",
        writable:false,
        enumerable:false,
        configurable:false
    });
    
    //重新修改特性
    Object.defineProperty(obj,"newKey",{
        value:"hello",
        writable:true,
        enumerable:true,
        configurable:true
    });
    console.log( obj.newKey ); //报错:Uncaught TypeError: Cannot redefine property: newKey
    
    //第二种情况:configurable设置为true,可以再次修改特性。
    Object.defineProperty(obj,"newKey",{
        value:"hello",
        writable:false,
        enumerable:false,
        configurable:true
    });
    
    //重新修改特性
    Object.defineProperty(obj,"newKey",{
        value:"hello",
        writable:true,
        enumerable:true,
        configurable:true
    });
    console.log( obj.newKey ); //hello

    一旦使用Object.defineProperty给对象添加属性,那么如果不设置属性的特性,那么configurable、enumerable、writable这些值都为默认的false

    存取器描述

    当使用存取器描述属性的特性的时候,允许设置以下特性属性

    当设置或获取对象的某个属性的值的时候,可以提供getter/setter方法,没有的话则为undefined

    • getter 是一种获得属性值的方法

    • setter是一种设置属性值的方法

    注意:当使用了getter或setter方法,不允许使用writable和value这两个属性

    var obj = {};
    var initValue = 'hello';
    Object.defineProperty(obj,"newKey",{
        get:function (){
            //当获取值的时候触发的函数
            return initValue;    
        },
        set:function (value){
            //当设置值的时候触发的函数,设置的新值通过参数value拿到
            initValue = value;
        }
    });
    //获取值
    console.log( obj.newKey );  //hello
    
    //设置值
    obj.newKey = 'change value';
    
    console.log( obj.newKey ); //change value

    get或set不是必须成对出现,任写其一就可以。如果不设置方法,则get和set的默认值为undefined

          let obj = {
              num:4
          };
           let n = 2;
          Object.defineProperty(obj,'num',{
              get:function(){   //取 obj.num 属性时会触发 get 方法
                  /*数据劫持*/
                  //当你获取这个属性的时候,会调用
                   n += 2;
                  return n;
              },
           set(val){   //给 obj.num 赋值时会触发 set 方法
             //val 是给 obj.num 赋值时的那个值 
           }
    
          });
          console.log(obj.num < 5 && obj.num > 5);//true
      /*num即小于5,又大于,就是应为,第一次判断obj.num时num=(n+=2)=4,符合了第一个条件,此时的n=4。
     读到第二个判断的时候,再次触发函数,此时n+=之后为6,又符合了第二个判断条件,所以出现了true*/        
  • 相关阅读:
    node.js的安装与第一个hello world、node.js的初始化
    微信小程序组件学习中
    jq 滚轮监听事件
    数据库的优化(转)
    jquery zTree的基本用法
    Linux常用命令大全
    软件架构与设计 百度网盘的pdf电子书籍
    项目:IT资源共享资源(登录后端)<2>
    项目:IT资源共享资源(登录前端)<1>
    Node简单服务器开发
  • 原文地址:https://www.cnblogs.com/theblogs/p/10500072.html
Copyright © 2011-2022 走看看