元编程

这个代理反射对象允许您拦截和定义基本语言操作的自定义行为(例如,属性查找、赋值、枚举、函数调用等)。在这两个对象的帮助下,您可以在JavaScript的元级编程。

代理人

代理对象允许您拦截某些操作并实现自定义行为。

例如,获取对象的属性:

js型
常量处理程序={get(目标,名称){在目标中返回名称?目标[名称]:42;},};const p=新代理({},处理程序);p.a=1;控制台日志(p.a,p.b);//1, 42

这个代理对象定义目标(此处为空对象)和处理程序对象,其中得到 陷阱已实现。这里,被代理的对象不会返回未定义获取未定义的属性时,但将返回数字42.

其他示例可在代理参考页。

术语

当谈论代理的功能时,使用以下术语。

处理程序

包含陷阱的占位符对象。

陷阱

提供属性访问的方法。(这类似于陷阱在操作系统中。)

目标

代理虚拟化的对象。它通常用作代理的存储后端。针对目标验证关于对象非扩展性或非配置属性的不变量(保持不变的语义)。

不变性

调用在实现自定义操作时保持不变的语义不变性。如果违反了处理程序的不变量类型错误将被抛出。

处理程序和陷阱

下表总结了可用的陷阱代理物体。请参阅参考页以获取详细的解释和示例。

处理器/陷阱 抢断
handler.getPrototypeOf() Object.getPrototypeOf()
反射.getPrototypeOf()
__原型__
Object.prototype.isPrototypeOf()
运算符
handler.setPrototypeOf() Object.setPrototypeOf()
反射.setPrototypeOf()
处理程序.isExtensible() 对象.isExtensible()
反射可扩展()
handler.preventExtensions() Object.proventExtensions()
反射.prventureExtensions()
handler.getOwnPropertyDescriptor() 对象.getOwnPropertyDescriptor()
反射.getOwnPropertyDescriptor()
处理程序.defineProperty() 对象.defineProperty()
反射定义属性()
handler.has()
属性查询
代理中的foo
继承的属性查询
Object.create中的foo(代理)
反射has()
handler.get()
财产访问权
代理【foo】
代理.巴
继承的属性访问
对象.创建(代理)【foo】
反射.get()
handler.set()
财产转让
代理[foo]=巴
代理.foo=巴
继承的属性分配
对象.创建(代理)[foo]=巴
反射集()
handler.deleteProperty()
属性删除
删除代理【foo】
删除代理.foo文件
反射删除属性()
handler.ownKeys() 对象.getOwnPropertyNames()
Object.getOwnPropertySymbols()
Object.keys()
反射.ownKeys()
处理程序.apply() 代理(..args)
函数.prototype.apply()函数.prototype.call()
反射.apply()
handler.construct()处理程序 新代理(…args)
Reflect.construct()

可撤销代理

这个代理.可撤销()方法用于创建可撤销代理对象。这意味着可以通过函数撤销代理撤销并关闭代理。

之后,对代理的任何操作都会导致类型错误.

js型
const revocable=代理可撤销({},{get(目标,名称){返回`[[${name}]]`;},},);const proxy=可撤销代理;console.log(proxy.foo);//“[[foo]]”revotable.revoke();console.log(proxy.foo);//TypeError:无法对已吊销的代理执行“get”proxy.foo=1;//TypeError:无法对已吊销的代理执行“set”删除proxy.foo;//TypeError:无法对已吊销的代理执行“deleteProperty”console.log(代理类型);//“object”,typeof不会触发任何陷阱

反思

反射是一个内置对象,为可截取的JavaScript操作提供方法。方法与代理处理程序的.

反射不是函数对象。

反射帮助将默认操作从处理程序转发到目标.

使用反射has()例如,您可以获得在里面操作人员作为函数:

js型
Reflect.has(Object,“分配”);//真的

更好的apply()函数

之前反射,通常使用函数.prototype.apply()方法调用具有给定价值和论据作为阵列(或阵列状对象).

js型
函数.prototype.apply.call(Math.floor,未定义,[1.75]);

使用反射应用程序这变得不那么冗长,也更容易理解:

js型
反射应用(数学地板,未定义,[1.75]);// 1反射应用(字符串.fromCharCode,未定义,[104101108111]);//“你好”反射应用(RegExp.prototype.exec,/ab/,[“confabulation”]).index;// 4Reflect.apply(“”.charAt,“小马”,[3]);//“i”

检查属性定义是否成功

使用对象定义属性,如果成功则返回对象,或抛出类型错误否则,您将使用尝试。。。抓住块捕获定义属性时发生的任何错误。因为反射定义属性()返回布尔成功状态,您可以只使用如果…否则在此阻止:

js型
if(Reflect.defineProperty(目标、属性、属性)){//成功}其他{//故障}