JS中Proxy对象的handler参数详解

intro

ES6新特性中新增代理类Proxy,其构造方法为Proxy(target, handler),其中:
- target 被代理的对象|目标
- handler 处理器|中间层代理(用于自定义代理对象的各种可代理操作)。
targethandler都是对象。
handler中的成员方法是固定的(用途也是固定)。

API

handlder对象中共有13种可代理操作,如下:
(如果没有定义某种操作,那么这种操作会被转发到目标对象上)
getPrototypeOf(target) 当读取被代理对象target的原型prototype时会触发该操作。
setPrototypeOf(target, prototype)target设置prototype时触发。

isExtensible(target) 判断target是否可扩展时触发。
preventExtensions(target) 设置target不可扩展时触发。

getOwnPropertyDescriptor(target, prop) 获取target[prop]的属性描述时触发。
defineProperty(target, property, descriptor) 定义target的某个属性prop的属性描述descriptor时触发。

has(target, prop) 当判断target是否拥有属性prop时,触发。

get(target, property, receiver) 读取target的属性property时触发。
set(target, property, value, receiver) 设置target的属性property为值value时触发。
get中的receiverProxy继承Proxy的对象
set中的receiver最初被调用的对象(通常是Proxy本身)

deleteProperty(target, property) 删除target的属性property时触发。
ownKeys(target) 获取targeet的所有属性key s时触发。

apply(target, thisArg, argumentsList) 当目标target为函数,且被调用时触发。
construct(target, argumentsList, newTarget)target为构造函数的代理对象构造实例时触发。

detail

  • handler.getPrototypeOf(target) 返回一个对象或null(不能返回其他类型的原始值)

    • JS中,以下5种操作会触发JS引擎读取一个对象的原型(getPrototypeOf(target)代理方法的运行)。
      • Object.getPrototypeOf(object) 返回对象object的原型prototype。
      • Reflect.getPrototypeOf(target)
      • __proto__ 对象的该属性是一个访问器属性(一个getter函数和一个setter函数)。
      • obj1.isPrototypeOf(obj2) 测试对象obj1是否在对象obj2的原型链上。
      • object instanceof constructor 检测构造函数constructor的prototype属性是否出现在对象object的原型链中的任何位置。
  • handler.setPrototype(target, prototype) 返回Boolean值,表示是否修改了原型。

    • 本方法可以拦截的操作有:
      • Object.setPrototypeOf(object, prototype)
      • Reflect.setPrototypeOf(target, prototype)
  • handler.isExtensible(target) 返回一个Boolean值(或一个可转换为Boolean值的值)

    • 会拦截以下操作:
      • Object.isExtensible(object)
      • Reflect.isExtensible(target)
  • handler.preventExtensions(target) 返回一个Boolean值

    • 拦截的操作:
      • Object.preventExtensions(object)
      • Reflect.preventExtensions(target)
  • handler.getOwnPropertyDescriptor(target, prop) 返回一个objectundefined

    • 拦截的操作:
      • Object.getOwnPropertyDescriptor(object, prop)
      • Reflect.getOwnPropertyDescriptor(target, prop)
  • handler.defineProperty(target, property, descriptor 返回一个Boolean值,表示操作成功/失败

    • 拦截的操作:
      • Object.defineProperty(object, property, descriptor)
      • Reflect.defineProperty(target, property, descriptor)
  • handler.has(target, prop) 返回一个Boolean值

    • handler.has(target, prop)可以看做是in操作的trap。()
      • 属性查询: foo in proxy
      • 继承属性查询: foo in Object.create(proxy)
      • with检查: with(ptoxy) {(foo);}
      • Reflect.has(target, prop)
  • handler.get(target, property, receiver) get可以返回任何类型的值

    • 拦截的操作:
      • 读属性: proxy[foo]proxy.foo
      • 访问原型链上的属性: Object.create(proxy)[foo]
      • Reflect.get(target, property, ?receiver)
  • handler.set(target, property, value, receiver 返回Boolean值,表示写操作是否成功。

    • 拦截的操作:
      • 写属性: proxy[foo] = xxxproxy.foo = xxx
      • 指定继承者的属性: Object.create(proxy)[foo] = xxx
      • Reflect.set(target, property, value, ?receiver)
  • handler.deleteProperty(target, property 返回Boolean值,表示删除是否成功。

    • 拦截的操作:
      • 删除属性: delete proxy[foo]delete proxy.foo
      • Reflect.deleteProperty(target, property)
  • handler.ownKeys(target) 返回一个可枚举对象

    • 拦截的操作:
      • Object.getOwnPropertyNames(object) 返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括Symbol值作为名称的属性)组成的数组。
      • Object.getOenPropertySymbols(object) 返回一个给定对象自身的所有 Symbol 属性的数组。
      • Object.keys(object) 返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和使用 for…in 循环遍历该对象时返回的顺序一致 。
      • Reflect.ownKeys(target) 返回一个由目标对象自身的属性键组成的数组。
  • handler.apply(target, thisArg, argumentsList) 可以返回任何类型的值。

    • 拦截的操作:
      • proxy(...args)
      • Function.prototype.apply()Function.prototype.call()。(即foo.apply()foo.call())
      • Reflect.apply(target, thisArg, argumentsList)
  • handler.construct(target, argumentsList, newTarge) 返回一个对象

    • 拦截的操作:
      • new proxy(...args
      • Reflect.construct(target, argumentsList, newTarget)

link

handler|处理器对象 - JavaScript | MDN

你可能感兴趣的:(JS)