Object.defineProperty以及数据代理

64 阅读2分钟
       Object.defineProperty()方法会直接在对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。

备注:

    (1)应当直接在Object构造器对象上调用此方法,而不是在任意一个Object类型的实例
         上调用。

语法:
    Object.defineProperty(obj, prop, descriptor)
参数:
    obj:要定义属性的对象
    prop:要定义或修改的属性的名称或Symbol
    descriptor:要定义或修改的属性描述符
返回值:被传递给函数的对象。 
描述:
    该方法允许精确地添加或修改对象的属性。通过赋值操作添加的普通属性是可枚举的,
    在枚举对象属性时会被枚举到 (for...inObject.keys方法),可以改变这些属性的值,
    也可以删除这些属性。这个方法允许修改默认的额外选项(或配置)。默认情况下,
    使用Object.defineProperty()添加的属性值是不可修改的。    
描述符(descriptor):  
    :
    (1) configurable(数据属性描述符、存取属性描述符公有):
    当且仅当该属性的configurable键值为true时,该属性的描述符才能够被改变,
    同时该属性也能从对应的对象上被删除。
    默认值: false
    
    (2) enumerable(数据属性描述符、存取属性描述符公有)
    当且仅当该属性的enumerable键值为true时,该属性才会出现在对象的枚举属性中。
    默认值:false
    当设置为false时,该对象中的属性无法被for...inObject.keys枚举出来,其它方式能
    正常取值        
    
    (3)  value(数据属性描述符)
    该属性对应的值。可以是任何有效的javaScript值(数值,对象,函数等)
    默认值:undefined     
    
    (4) writable(数据属性描述符)
    当且仅当该属性的writable键值为true时,属性的值,也就是上面的value,才能
    被赋值运算符改变。
    默认值为false      
    
    (5) get(存取属性描述符)
    属性的getter函数,如果没有getter,则为undefined。当访问该属性时,会调用此函数
    执行时不传入任何参数,但是会传入this对象(由于继承关系,这里的this并不一定是
    定义该属性的对象)。该函数的返回值会被用作属性的值
    默认为:undefined   
    
    (6) set(存取属性描述符)
    属性的setter函数,如果没有setter,则为undefined。当属性值被修改时,会调用此函数
    该方法接受一个参数(也就是被赋予的新值),会传入赋值时的this对象。
    
    
    

实现数据如下

    <script>
       let obj1={x:1}
       let obj2={y:2}
       Object.defineProperty(obj2,'x',{
         get(){
           return obj1.x
         }
         set(value){
           obj1.x = value
         }
       })
    </script>

vue中的数据代理:通过vm对象来代理data对象中属性的操作 vue中的数据代理优点:更加方便的操作data中的数据 基本原理: 通过Object.defineProperty()把data对象中所有属性添加到vm上 为每一个添加到vm上的属性都指定一个getter和setter 在getter/setter内部去操作(读/写)data中对应的属性