快速理解Object.defineProperty( )

2019-06-17  本文已影响0人  chenM_

原文地址

关于Object.defineProperty()

MDN解释:Object.defineProperty()方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。

本文简单的讲解了 Object.defineProperty 有助于你快速了解 Object.defineProperty 想要详细学习请移至MDN文档

我的理解就是 当你操作一个对象(修改或者删除属性)时,Object.defineProperty可以控制是否可以去操作这个对象(修改、删除属性)或者修改、获取属性值时拦截你的操作然后do something。

语法 Object.defineProperty(obj, prop, descriptor)


obj 要操作的对象

prop 要定义或修改的属性的名称

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

先看一下基本使用,然后下面会具体讲解一下属性描述符。


var obj = {};

Object.defineProperty(obj,'name',{

    value:'chenm'

});

console.log(obj.name); //chenm


descriptor属性描述符

分为数据描述符和存取描述符


configurable:为 true 时,该属性描述符才能够再次被改变,同时该属性也能从对应的对象上被删除。默认为 false。

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

value:该属性的值,默认为 undefined。

writable:为true时,属性的值才能被 ‘=’ 赋值。默认为 false。

get:一个给属性提供 getter 的方法,如果没有 getter 则为 undefined。当访问(获取)该属性时,该方法会被执行,方法执行时没有参数传入,

但是会传入this对象(由于继承关系,这里的this并不一定是定义该属性的对象)。

set:一个给属性提供 setter 的方法,如果没有 setter 则为 undefined。当修改属性值时,触发执行该方法。该方法将接受唯一参数,即该属性新的参数值。

configurable:为 true 时,该属性描述符才能够再次被改变,同时该属性也能从对应的对象上被删除。默认为 false。

//1.configurable为false

var obj = {age:25};

Object.defineProperty(obj,'name',{

    configurable:false,

    value:'chenm'

});

delete obj.name;

console.log(obj.name); //chenm

//configurable 为false时(当然默认就为false),name不允许被删除,所以打印obj.name 还是chenm

//注意当操作对象现有属性的时候 configurable默认为true

//2.configurable为 true

Object.defineProperty(obj,'age',{

    value:'26'

});

delete obj.age;

console.log(obj.age); //undefined

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

//1.enumerable为false

var obj = {age:25};

Object.defineProperty(obj,'name',{

    enumerable:false,

    value:'chenm'

});

for(let key in obj){

    console.log(key)    //age

}

console.log(Object.keys(obj))//["age"]

//Object.keys:返回该对象可枚举属性组成的数组。 enumerable为false时,name并不能枚举。

//注意当操作对象现有属性的时候 enumerable默认为true

//2.enumerable为true

var obj = {age:25};

Object.defineProperty(obj,'name',{

    enumerable:true,

    value:'chenm'

});

for(let key in obj){

    console.log(key) //age name

}

console.log(Object.keys(obj)) //["age","name"]

value:该属性的值,默认为 undefined。

var obj = {};

Object.defineProperty(obj,'name',{

    value:'chenm'

});

console.log(obj.name); //chenm

Object.defineProperty(obj,'sex',{



});

console.log(obj.sex); //undefined

//不设置value时 改属性的值为 undefined

writable:为true时,属性的值才能被 ‘=’ 赋值。默认为 false。

//1.writable为false

var obj = {};

Object.defineProperty(obj,'sex',{

    writable:false,

    value:'boy'

});

console.log(obj.sex); //boy

obj.sex = 'girl';

console.log(obj.sex); //boy

//writable 为false(默认就为false),sex是不能用'='赋值的。

//2.writable为true

var obj = {};

Object.defineProperty(obj,'sex',{

    writable:true,

    value:'boy'

});

console.log(obj.sex)  //boy

obj.sex = 'girl'

console.log(obj.sex)  //girl

get:一个给属性提供 getter 的方法。当访问(获取)该属性时,该方法会被执行。
set:一个给属性提供 setter 的方法。当修改该属性值时,该方法会被执行。

var obj = {};

let val = '15k';

Object.defineProperty(obj,'wages',{

    get:function(){

    //这是里获取属性的时候执行

    console.log('我获取到你的值了。。。')

    return val;

    },

    set:function(newVal){

        //这是里修改属性值的时候执行

        console.log('我修改了你的值。。。')

    val = newVal

    }

});

console.log(obj.wages);

obj.wages = '20k'

console.log(obj.wages);

//我获取到你的值了。。。

//15k

//我修改了你的值。。。

//我获取到你的值了。。。

//20k


//get,set一起出现,如果省略get,获取到的值都是undefined

var obj = {};

let val = '15k';

Object.defineProperty(obj,'wages',{

    set:function(newVal){

        //这是里修改属性值的时候执行

        console.log('我修改了你的值。。。')

        val = newVal

    }

});

console.log(obj.wages) //undefined

obj.wages = '20k'

console.log(obj.wages)//undefined

//如果省略set, 无法赋值。

var obj = {};

let val = '15k';

Object.defineProperty(obj,'wages',{

    get:function(){

    //这是里获取属性的时候执行

    console.log('我获取到你的值了。。。')

    return val;

    },

});

console.log(obj.wages) //15k

obj.wages = '20k'

console.log(obj.wages)//15k

注意:


//get,set与writable,value不能共用

var obj = {};

let val = '15k';

Object.defineProperty(obj,'wages',{

    value:'20k'

    set:function(newVal){

        //这是里修改属性值的时候执行

        console.log('我修改了你的值。。。')

    val = newVal

    }

});

//Uncaught SyntaxError: Unexpected identifier

tips:操作对象的现有属性和用Object.defineProperty()添加的属性,描述符的默认值是有所的同的。


现有属性描述符默认值:

configurable:true

enumerable:true

writable:true

Object.defineProperty()添加的属性描述符默认值:

configurable:false

enumerable:false

writable:false


根据Object.defineProperty()的get,set写一个简单的数据双向绑定。

<!DOCTYPE html>

<html>

    <head>

    <meta charset="UTF-8">

    <title></title>

    </head>

    <body>

    <input type="text" id="input"/>

    <span id="text"></span>

    <button id="btn1">获取值</button>

    <button id="btn2">修改值</button>

    <script>

        var obj = {

            value:123

        };

        //初始化赋值

        document.getElementById('input').value = obj.value;

        document.getElementById('text').innerHTML = obj.value;



        //监听input方法

        document.getElementById('input').oninput = function(e){
          obj.value = e.target.value;
        };
      //使用Object.defineProperty设置属性的get,set方法。
        let val = obj.value;
        Object.defineProperty(obj,'value',{
          get:function(){
              return val
          },
          set:function (newVal){
              //当值被修改的时候 修改input&span的值
              document.getElementById('input').value = newVal;
              document.getElementById('text').innerHTML = newVal;
              val = newVal;
           }
        });
        document.getElementById('btn1').onclick = function (){
          console.log(obj)
        }
       document.getElementById('btn2').onclick = function (){
          obj.value = '修改了';
        }
    </script>
    </body>
</html>

上一篇下一篇

猜你喜欢

热点阅读