Proxy in JavaScript

可以代理一个对象,对读取、赋值等操作做拦截,从而可额外地做一些事情,对于没有拦截的操作,则按原对象操作调用。

let p = new Proxy(target, handler);

通过 handler 来提供以下方法(this 指向 代理后的对象,该对象的 [[handler]] 指向 handler):

  • get(target, prop, receiver) 拦截属性读取操作
  • set(target, prop, val, receiver) 拦截设置属性值操作
  • has(target, prop) 可以看作是对 in 的操作的拦截
  • apply(target, thisArg, args) 拦截函数的调用,包括普通调用和 applycall 等。
  • construct(target, args, newTarget) 拦截 new 操作符
  • defineproperty(target, prop, descriptor) 拦截 Object.defineProperty 的操作
  • deleteProperty(target, prop) 拦截 delete 操作
  • getOwnPropertyDescriptor(target, prop) 拦截 Object.getOwnpropertyDescriptor
  • getPrototypeOf(target) 拦截原型对象的读取,包括 Object.getPrototypeOf()__proto__ 以及 instanceof
  • isExtensible(target) 拦截 Object.isExtensible()
  • ownKeys(target) 拦截 Object.getOwnPropertyNames() 以及 Object.keys()
  • preventExtensions(target) 拦截 Object.preventExtensions(obj)
  • setPrototypeOf(target, proto) 拦截 Object.setPrototypeOf

receiver,Proxy 或继承 Proxy 的对象,最初被调用的对象,通常就是 proxy 自身。但如果对象本身无该属性,原型链上有 Proxy 对象,那么这时对象本身就作为 receiver 参数传进来了。1

不仅使用于 Object,也使用于 Reflect,拦截具体对应的操作可能有所区别

Proxy.revocable(target, handler) 创建一个 proxy 并返回撤销该 proxy 的方法。

const { proxy, revoke } = Proxy.revocable(target, handler);
// .. do something with proxy
// 撤销代理
revoke();

参考