- A+
所属分类:Web前端
Proxy 定义
Proxy用于修改对象的某些行为,获取值,设置值等
let p = new Proxy(target, handler);
- target 用Proxy包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。
- 一个对象,其属性是当执行一个操作时定义代理的行为的函数。
Proxy.revocable()方法
let {proxy,revocable} = Proxy.revocable(target, handler);
- target,handler参数和new Proxy()一致。
- revoke()方法调用后,代理会变为无效状态。
示例如下:
handler对象
handler get
拦截对象属性值的获取。
get(target, property, receiver)
handler set
拦截对象属性值的设置。
set(target, property, value, receiver)
handler deleteProperty
拦截对象属性的删除
deleteProperty(target, property)
handler getOwnPropertyDescriptor
拦截获取对象属性描述。
getOwnPropertyDescriptor(target,property)
handler defineProperty
拦截定义对象属性的描述。
defineProperty(target,property,descriptor)
handler has
拦截判断对象属性是否存在
包括property in proxy 和 Reflect.has , 不包括Object.prototype.hasOwnProperty。
has(target,property)
handler ownKeys
拦截对象自身属性key值的读取操作,返回字符串或Symbol值数组。
- Object.getOwnPropertyNames()
- Object..getOwnPropertySymbols()
- Object.keys()
- for...in循环
ownKeys(target)
handler apply
拦截函数调用
apply(target,ctx,args)
handler construct
拦截构造函数调用。
construct(target,args)
handler getPrototypeOf
拦截获取对象的原型
- Object.prototype.__proto__
- Object.prototype.isPrototypeOf()
- Object.getPrototypeOf()
- Reflect.getPrototypeOf()
- instanceof
getPrototypeOf(target)
handler setPrototypeOf
拦截设置对象的原型。
- Object.prototype.__proto__
- Object.setPrototypeOf()
- Reflect.setPrototypeOf()
setPrototypeOf(target,proto)
handler isExtensible
拦截判断对象是否可扩展
isExtensible(target)
handler preventExtensions
拦截对象的组织扩展方法
preventExtensions(target)
更多关于handler规范,请参考es2015规范的26.2.2章节。
实际应用
监听某个对象,在执行该对象的所有函数时,打印执行前后的日志。
let obj = { id: 100, say: function () { console.log('say exec'); return 'xxx' } } let handler = { get: function (target, property, receiver) { let value = Reflect.get(target, property, receiver) if (typeof value === 'function') { return function (...rest) { console.log(`before ${property} exec.`); let res = Reflect.apply(value, target, rest); console.log(`after ${property} exec.`); return res; } } else { return value; } }, } let proxy = new Proxy(obj, handler); proxy.id proxy.say()