从Object.definedProperty中看vue的双向数据的绑定

前言

Object.defineProperty是ES5中的方法,它可以直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。vue.js正式利用这种方法实现数据的双向绑定,以达到响应式的目的。

1、语法

Object.defineProperty(object, propertyname, descriptor) //参数(3个且必须)

2、参数详解

  • object:要在其上添加或修改属性的对象。
  • propertyname:一个包含属性名称的字符串。就是需要定义的属性和方法。
  • descriptor:,描述符
  • 描述符默认值汇总
    拥有布尔值的键 configurable、enumerable 和 writable 的默认值都是 false。
    属性值和函数的键 value、get 和 set 字段的默认值为 undefined。
  1. value:属性的值
  2. writable:如果为false,属性的值就不能被重写,只能为只读了。
  3. enumerable:是否能枚举,也就是否能在for…in循环中遍历出来或在Object.keys中列举出来。
  4. configurable:当且仅当该属性的 configurable 键值为 true 时,该属性的描述符才能够被改变,同时该属性也能从对应的对象上被删除。默认为 false。。

还有两个方法 (双向数据绑定正是利用了这两个方法,即访问器 )get() 和 set()

3、看看例子:

 let a = {
    
    };
 Object.defineProperty(a, 'b', {
    
    
        value: '我是b的值'
    })
    console.log(a.b); //我是b的值

就是给a对象添加b属性,并返回a对象;
把描述设置为可写是什么样的呢?

 let a = {
    
    };
Object.defineProperty(a, 'b', {
    
    
      value: '我是b的值',
      writable: true
  })
  a.b = '重新给b赋值';
  console.log(a.b); //重新给b赋值

4、访问器 set和get

set();一旦属性被重新赋值,此方法被自动调用。
get();一旦属性被访问读取,此方法被自动调用。
不能同时设置访问器 (get 和 set) 和 wriable 或 value,否则会错。

let a = {
    
    };

Object.defineProperty(a, 'b', {
    
    
    // value: '我是b的值',
    // writable: true,
    // configurable: true,
    set: function(val) {
    
    
        console.log('a.b被赋值为', val);
    },
    get: function() {
    
    
        console.log('取值的时候调用');
    }
})
a.b = '重新给b赋值';
console.log(a.b);

在这里插入图片描述

5、简单双向数据绑定

给对象a定义新的属性b,并且定义属性b的get和set方法,当a.b的时候会调用b属性的get方法,给b属性赋值的时候,会调用set方法,这就是修改数据的时候,视图会自动更新的关键.(只能兼容IE8以上的浏览器,vue也是如此!)。

  <P>输入: <input type="text" id="dom1"></P>
    <P>输出: <input type="text" id="dom2"></P>
    <script>
        var a = {
    
    };
        var updata = [];
        Object.defineProperty(a, 'b', {
    
    
            set: function(val) {
    
    
                updata['b'] = val
            },
            get: function() {
    
    
                return updata['b']
            }
        })
        dom1.onkeyup = function() {
    
    
            a.b = dom1.value;
            dom2.value = updata['b']
        }
    </script>

在这里插入图片描述

6、再看看Object.defineProperty实践例子

直接在原型上添加一个不可遍历的方法extend(),该方法可以把新对象赋值给旧对象;

Object.defineProperty(Object.prototype, 'extend',{
    
    
  value : function(def, opt) {
    
    
        for(var key in opt){
    
    
            def[key] = opt[key];
        }
    return def;
  },
  writable: true,
  enumerable : false
});
 
function func(options){
    
    
    let def = {
    
    
        payType: 'wechat',
        buyType: -1,
        isCard: false,
        toUid: -1,
        couponId: -1
    };
  
    let opt = extend(def, options);
  
    this.isCardPay = opt.isCard;
    this.payType = opt.payType;
    .......
}
  
//使用
func({
    
    
    payType: 'ali',
    buyType: 2,
    isCard: true,
    toUid: 123456,
    couponId: 667890
})

7、vue怎么实现数据双向绑定?

vue.js 则是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。

猜你喜欢

转载自blog.csdn.net/qq_47008195/article/details/108697425
今日推荐