ES6中的Proxy

10月初,Vue3.0预览版发布,其中一个重要改变就是数据绑定实现方式由 getter/setter 变为 Proxy。那么Proxy究竟是何方神圣,我们可以在哪些场景使用呢?

在MDN中的表述:Proxy 对象用于定义基本操作的自定义行为(如属性查找,赋值,枚举,函数调用等)。

从中可以看出,他的核心功能是 自定义行为 

语法很简单

let p = new Proxy(target, handler);

可以代理的操作列表如下(点击链接到MDN查看详细使用说明):

  1. handler.apply(target, thisArg, argumentsList) 拦截函数调用
  2. handler.construct(target, args) 拦截new操作符
  3. handler.defineProperty(target, property, descriptor) 拦截对对象的 Object.defineProperty() 操作
  4. handler.deleteProperty(target, property) 拦截delete属性
  5. handler.enumerate()已废弃
  6. handler.get( target, property, receiver) 拦截取值操作
  7. handler.getOwnPropertyDescriptor()
  8. handler.getPrototypeOf()
  9. handler.has()
  10. handler.isExtensible()
  11. handler.ownKeys()
  12. handler.preventExtensions()
  13. handler.set(obj, prop, value) 拦截赋值操作
  14. handler.setPrototypeOf()

 通常我们这样使用代理类来操作,隐藏被代理的目标:

var target = { a:1, b:2 } //定义一个被代理的对象
target = new Proxy(target, handler);
target.a = 10; //handler.set 函数会被调用

 一个简单的应用场景,要设置一个人的年龄范围0-100:

var person = { age: 1 };

person = new Proxy( person, {
  set: function( target, prop, value ){
    if (prop === 'age') {
      if( typeof value !== 'number' ) throw new Error('age value type error');
      target[prop] = value < 0 ? 0 : ( value > 100 ? 100 : value );
    } else {
      return Reflect.set(...arguments);
    }
  }
});

console.log( person.age );  //1

person.age = -1;
console.log( person.age );  // 0

person.age = 200;
console.log( person.age ); // 100

person.age = 50;
console.log( person.age ); // 50

person.age = 'some';  //age value type error

这样,代理的应用场景就显而易见了:

  • 需要对默认行为进行干预的时候,用就对了
  • 需要完美地添加附加行为,同时不影响外部调用方式。

猜你喜欢

转载自www.cnblogs.com/xinxiangbin/p/11756701.html