详解Object.defineProperty

2019-07-23  本文已影响0人  isSunny

说到vue实现响应式的实现原理,我们都知道是通过Object.defineProperty,那么具体是怎么实现的呢?今天我们就来详细的探讨一下Object.defineProperty吧。

1.Object.defineProperty是什么?

官方解释:该方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。
顾名思义,就是为对象定义属性。
我们都知道,为对象定义属性或者修改属性,我们常用的有.操作符或者[""]操作符,.操作符被称为“属性访问”,[""]被称为“键访问”

image.png

我们如果要增加一个新属性或者修改一个已有的属性并且它的特性进行设置,就需要用到Object.defineProperty了。

语法

Object.defineProperty(obj, prop, descriptor)

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

属性描述符

var obj = {
        a:1
}
Object.defineProperty(obj,"a",{
        value:2,
        writable:false
})
console.log(obj.a);//2
obj.a = 3;
console.log(obj.a);//2
var obj={
        a:1,
        b:2
    }
Object.defineProperty(obj,"a",{
        value:2,
        writable:false,
        enumerable:false
})
for(var key in obj){
     console.log(key)//b
}
var obj={
        a:1,
}
Object.defineProperty(obj,"a",{
        value:2,
        writable:false,
        enumerable:false,
        configurable:false
})
Object.defineProperty(obj,"a",{
        value:4,
        writable:true,
        enumerable:false,
        configurable:true
})
 console.log(obj.a);//Uncaught TypeError

var obj={
        a:1,
}
Object.defineProperty(obj,"a",{
        value:2,
        writable:true,
        enumerable:false,
        configurable:true
})
console.log(obj.a);//2
obj.a = 3;
console.log(obj.a);//3
Object.defineProperty(obj,"a",{
        value:4,
        writable:false,
        enumerable:false,
        configurable:true
    })
 console.log(obj.a);//4
 obj.a= 5;
 console.log(obj.a);//4

另外,configurable变成false还会禁止删除这个属性delete

var obj={
        a:1,
    }
    delete obj.a;
    console.log(obj.a);//undefined
    Object.defineProperty(obj,"a",{
        value:2,
        writable:true,
        enumerable:false,
        configurable:false
    })
    delete obj.a;
    console.log(obj.a);//2

存取描述符

var o = {};
var num = 5;
Object.defineProperty(o,"a",{
    get:function(){
         console.log("获取值");
        return num;
    },
    set:function(val){//val参数代表的是新设置的值
       console.log("设置值");
        num= val+1;
    }
})
o.a = 10;
console.log(o.a);//11
o.a = 11;
console.log(o.a);//12
console.log(num);//12
image.png

实现双向绑定demo-MVVM

<body>
    <h2>实现一个简单的双向绑定</h2>
    <input type="text" id="inp">
    <p id="Txt"></p>
<script type="text/javascript">
    var inp = document.querySelector("#inp");
    var Content = document.querySelector("#Txt");
    var obj={};
    Object.defineProperty(obj,"inVal",{
        get:function(){
            return this._defaultVal;
        },
        set:function(newVal){
            this._defaultVal = newVal;
            inp.value = newVal;
            Content.innerText =newVal;
        }
    })
    inp.onkeyup= function(){
        obj.inVal = this.value;
    }
    setTimeout(() => {
        obj.inVal ="";
    }, 5000);
</script>
image.png
上一篇 下一篇

猜你喜欢

热点阅读