proxy

作者: zooey1184 | 来源:发表于2019-06-26 14:11 被阅读0次

    双向数据绑定3


    使用defineProperty能实现数据层的双向绑定,优点是兼容性较高,属于es5的特性,缺点是数据劫持无法监听深层的数据变化,明显的是数据的变化需要额外的逻辑判断并且只能劫持对象属性,如果属性值也是对象,则需要遍历深层,显然能劫持一个完整的对象是我们想要的

    所以就有了第二种方式实现双向数据绑定--Proxy(代理)

    Proxy 用于修改某些操作的默认行为,等同于在语言层面做出修改,所以属于一种“元编程”(meta programming),即对编程语言进行编程。Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。

    同defineProperty一样,Proxy也是通过set和get是想双向数据绑定

    [set] && [get]

    get(target, key, reciver)

    // target: 目标对象
    // key: 目标属性
    // reciver: proxy实例本身
    var person = {
      name: "张三"
    };
    
    var proxy = new Proxy(person, {
      get: function(target, property) {
        if (property in target) {
          return target[property];
        } else {
          throw new ReferenceError("Property \"" + property + "\" does not exist.");
        }
      }
    });
    proxy.name // "张三"
    proxy.age // 抛出一个错误
    

    set(target, key, value, reciver)

    // target: 目标对象
    // key: 目标属性
    // value: 属性值
    // reciver: proxy实例本身
    let validator = {
      set: function(obj, prop, value) {
        if (prop === 'age') {
          if (!Number.isInteger(value)) {
            throw new TypeError('The age is not an integer');
          }
          if (value > 200) {
            throw new RangeError('The age seems invalid');
          }
        }
    
        // 对于满足条件的 age 属性以及其他属性,直接保存
        obj[prop] = value;
      }
    };
    
    let person = new Proxy({}, validator);
    
    person.age = 100;
    
    person.age // 100
    person.age = 'young' // 报错
    person.age = 300 // 报错
    
    

    优点

    • proxy可以劫持整个对象而非一个属性
    • proxy可以直接监听数组的变化
    • proxy的支持方法比defineProperty多

    缺点

    • Proxy的劣势就是兼容性问题,而且无法用polyfill磨平

    相关文章

      网友评论

          本文标题:proxy

          本文链接:https://www.haomeiwen.com/subject/pmrccctx.html