Object.defineProperty() 方法是在指定对象上添加一个新属性,或者修改对象上的一个现有属性,然后返回该对象。
Object.defineProperty(obj, prop, descriptor)
在ie8只能在DOM对象上使用,如果在原生的对象使用 Object.defineProperty()会报错。
我这里就叫属性特性描述参数吧,那我为什么会叫属性特性描述参数呢?比如说在descriptor 里面可以设置属性的读写删除权限,以及是否可以被枚举。有了这些权限,那么对这个属性就更好控制了。
| 名称 | 说明 | 返回类型 | 默认值 | 
|---|---|---|---|
| value | 属性对应的值,可以使任意类型的值 | undefined | undefined | 
| writable | 属性的值是否可以被重写 | boolean | false | 
| enumerable | 是否可以被枚举(使用for...in或Object.keys()) | boolean | false | 
| configurable | 是否可以删除目标属性或是否可以再次修改属性的特性(writable, configurable, enumerable) | boolean | false | 
| get | getter 获得属性值的方法 | function | |
| set | setter 设置属性值的方法 | function | 
对象属性添加特性描述,提供两种形式来添加:
直接给属性添加对应的权限。比如下面的例子中,给obj的msg属性添加可枚举、可重写、可读、不可删除的权限。
var obj  = {
    msg:'hello'
}
Object.defineProperty(obj,"msg",{
    configurable:false,
    enumerable:true
    value:'hello world',
    writable:true
});
使用存取器描述属性特性的时候 ,没有value 和 writable。取而代之的是 set 和 get
var obj = {};
Object.defineProperty(obj,"msg",{
    get:function (){},
    set:function (value){}
    configurable: false
    enumerable: true
});
利用Object.defineProperty()方法来实现双向绑定。vue2也是使用Object.defineProperty()来实现的额。下面是双向绑定的完整实例:
<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>
<div id="app"></div>
<input type="" value="" id="input">
<script type="text/javascript">
    var obj = {}
    function watch(obj ,name ,callback){
        Object.defineProperty(obj,name,{
            set(newValue){
                value = newValue
                callback(newValue)
            },
            get(value){
                return value
            }
        })
    }
    function dosome(val){
        app.innerHTML = val
        input.value = val
    }
    var input = document.getElementById('input'),app = document.getElementById('app')
    input.oninput=function(e){
        var value = e.target.value
        obj['msg'] = value
    }
    watch(obj ,'msg' ,dosome)
</script>
</body>
</html>