Skip to content

Latest commit

 

History

History
52 lines (35 loc) · 2.19 KB

11.ES6的proxy的理解.md

File metadata and controls

52 lines (35 loc) · 2.19 KB

proxy,代理器用于修改某些操作的默认行为,包括但不限于拦截默认的get/set等方法。

  // target:拦截的目标对象,handler:定制拦截行为
  const proxy = new Proxy(target, handler)

Proxy.revocable()方法返回一个可取消的 Proxy 实例

  let target = {};
  let handler = {};

  let {proxy, revoke} = Proxy.revocable(target, handler);

  proxy.foo = 123;
  proxy.foo // 123
  // 取消实例
  revoke();
  proxy.foo // TypeError: Revoked

拦截方式

  • get():拦截对象属性读取
  • set():拦截对象属性设置,返回布尔
  • has():拦截对象属性检查k in obj,返回布尔
  • deleteProperty():拦截对象属性删除delete obj[k],返回布尔
  • defineProperty():拦截对象属性定义Object.defineProperty()、Object.- - - - defineProperties(),返回布尔
  • ownKeys():拦截对象属性遍历for-in、Object.keys()、Object.getOwnPropertyNames()、Object.getOwnPropertySymbols(),返回数组

重点难点

  • 要使Proxy起作用,必须针对实例进行操作,而不是针对目标对象进行操作
  • 没有设置任何拦截时,等同于直接通向原对象
  • 属性被定义为不可读写/扩展/配置/枚举时,使用拦截方法会报错
  • 代理下的目标对象,内部this指向Proxy代理

优势:

  • 可以直接监听对象而非属性

  • 可以直接监听数组的变化

  • 有13种拦截方法,不限于 apply、ownKeys、deleteProperty、has 等

  • 返回一个新对象,Object.defineProperty只能遍历对象属性修改

  • 性能比较好

Reflect:是ES6引入的一个新的对象,他的主要作用有两点,一是将原生的一些零散分布在ObjectFunction或者全局函数里的方法(如applydeletegetset等等),统一整合到Reflect上,这样可以更加方便更加统一的管理一些原生API。其次就是因为Proxy可以改写默认的原生API,如果一旦原生API别改写可能就找不到了,所以Reflect也可以起到备份原生API的作用,使得即使原生API被改写了之后,也可以在被改写之后的API用上默认的`API