ECMAScript 6 Proxy
Proxy主要用于定义基本操作的自定义行为,包括属性查找、赋值、枚举、函数调用等。
Proxy(target, handler)构造函数接收两个参数,target为被代理的对象,handler为处理器对象,用来自定义代理对象的各种操作。目前,一共有 13 种可代理操作:
get(target, propery, receiver)
在读取代理对象的某个属性时触发该操作,比如在执行 proxy.foo 时。
const target = {
name: 'aaa',
};
const targetProxy = new Proxy(target, {
// 在读取代理对象的某个属性时触发该操作
get(target, property, receiver) {
return target[property] || null;
}
});
targetProxy.name === target.name; // true
targetProxy.x === null; // true通过proxy的get拦截可以轻松实现 readOnly 和单例模式。
set(target, propKey, value, receiver)
在给代理对象的某个属性赋值时触发该操作,比如在执行 proxy.foo = 1时。
可以通过设置代理对象的set处理器轻松的根据需求对对象的写入进行控制。
deleteProperty(target, property)
在删除代理对象的某个属性时触发该操作,比如在执行 delete proxy.foo时。
defineProperty(target, property, descriptor)
在定义代理对象某个属性时的属性描述时触发该操作,如Object.defineProperty()和Object.defineProperties()。
如果目标对象不可扩展, 将不能添加属性;
不能添加或者修改一个属性为不可配置的,如果它不作为一个目标对象的不可配置的属性存在的话;
如果目标对象存在一个对应的可配置属性,这个属性可能不会是不可配置的;
如果一个属性在目标对象中存在对应的属性,那么
Object.defineProperty(target, prop, descriptor)将不会抛出异常;在严格模式下,
false作为handler.defineProperty方法的返回值的话将会抛出TypeError。
has(target, property)
在判断代理对象是否拥有某个属性时触发该操作,如in运算符。
如果目标对象的某一属性本身不可被配置,则该属性不能够被代理隐藏
如果目标对象为不可扩展对象,则该对象的属性不能够被代理隐藏
has拦截对for...in循环不生效。
ownKeys(target)
在获取代理对象的所有属性键时触发该操作,如在 Object.getOwnPropertyNames(obj)时。
结果必须是一个数组;
数组的元素类型只能是
String或Symbol;结果列表必须包含目标对象的所有不可配置(non-configurable )、自有(own)属性的key;
如果目标对象不可扩展,那么结果列表必须包含目标对象的所有自有(own)属性的key,不能有其它值。
getOwnPropertyDescriptor(target, property)
在获取代理对象某个属性的属性描述时触发该操作,如:Object.getOwnPropertyDescriptor(obj, prop)。
必须返回一个
object或undefined如果属性作为目标对象的不可配置的属性存在,则该属性无法报告为不存在
如果属性作为目标对象的属性存在,并且目标对象不可扩展,则该属性无法报告为不存在
如果属性不存在作为目标对象的属性,并且目标对象不可扩展,则不能将其报告为存在
属性不能被报告为不可配置,如果它不作为目标对象的自身属性存在,或者作为目标对象的可配置的属性存在
Object.getOwnPropertyDescriptor(target)的结果可以使用Object.defineProperty应用于目标对象,也不会抛出异常
apply(target, context, args)
在调用一个目标对象为函数的代理对象时触发该操作,比如 proxy()、proxy.call()、proxy.apply()。
target必须可被调用
construct (target, args, newTarget)
target必须是一个合法的 constructor ,并且必须返回一个对象
getPrototypeOf(proxy)
在读取代理对象的原型时触发该操作,比如在执行Object.getPrototypeOf(proxy)时。
当同时触发处理器get和getPrototypeOf操作时,get的优先级更高。
setPrototypeOf(target, proto)
在设置代理对象的原型时触发该操作,如:Object.setPrototypeOf(proxy)。如果返回false会抛出个TypeError异常。
如果
target不可扩展,原型参数必须与Object.getPrototypeOf()的值相同。
isExtensible(target)
在判断一个代理对象是否是可扩展时触发该操作,如:Object.isExetensible(proxy)时。
Object.isExtensible(proxy)必须返回与Object.isExtensible(target)相同的值。
preventExtensions(target)
在让一个代理对象不可扩展时触发该操作,比如在执行Object.preventExtensions(proxy)时。如果返回false会抛出个TypeError异常。
如果
Object.isExtensible(proxy)是false,Object.preventExtensions(proxy)只能返回true。
最后更新于