javascript - 如何使用 JavaScript/TypeScript 在类代理处理程序中获取属性描述符
问题描述
使用类代理,我想在执行特定操作之前询问属性描述符;如果它是访问器,则做一件事,如果它是方法,则做另一件事,如果它是属性,则做第三件事。但问题是我不认为我正在寻找该功能的正确所有者:
type Constructor<T> = new (...args: any[]) => T
const handler: ProxyHandler<any> = {
get(target, propertyKey, receiver) {
const desc = Object.getOwnPropertyDescriptor(target, propertyKey)
console.log(desc) // undefined
return Reflect.get(target, propertyKey, receiver)
}
}
function Adapted<U extends Constructor<any> = Constructor<any>>(Base: U = Object as any) {
return class extends Base {
constructor(...args: any[]) {
super(...args)
return new Proxy(this, handler)
}
}
}
class Foo extends Adapted() {
method() { return "foo" }
}
new Foo().method() // "foo"
我必须走原型链直到找到正确的所有者吗?是不是更简单一些?
解决方案
评估直接原型似乎就足够了。谢天谢地,不必走原型链:
const handler: ProxyHandler<any> = {
get(target, propertyKey, receiver) {
const desc = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(target), propertyKey)
// do something based on desc type
return Reflect.get(target, propertyKey, receiver)
}
}
我不认为有一种实用的方法可以从超类中截取实例属性,所以我已经放弃了。对于我的特定用例,首先防止通过以下方式定义公共属性就足够了Object.freeze
:
function Adapted<U extends Constructor<any> = Constructor<any>>(Base: U = Object as any) {
return class extends Base {
constructor(...args: any[]) {
super(...args)
return Object.freeze(new Proxy(this, handler))
}
}
}
仍然允许实际使用:
class Foo extends Adapted() {
#prop: string
constructor(prop: string) {
super()
this.#prop = prop
}
get prop(): string {
return this.#prop
}
set prop(value: string) {
this.#prop = value
}
method() { return "method" }
}
class Bar extends Foo {
method2(){ return "method2" }
}
let foo = new Foo("prop1"),
bar = new Bar("prop2");
console.log(foo.prop) // prop1
console.log(bar.prop) // prop2
bar.prop = "12"
console.log(bar.prop) // "12"
推荐阅读
- c# - OpenXML SDK C#:如何将书签内容从 1 个单词文件复制到另一个单词文件
- vb.net - 父/子组合框
- reactjs - 你如何在 React 中进行 axios 错误处理(用于用户身份验证)?
- java - 使用 Java 从 td href 元素中提取链接
- postgresql - Big Sur 失败时的 PostgreSQL 安装
- jquery - JQuery禁用提交按钮,直到表单完全填满
- android - 当应用程序进入后台时,如何在屏幕中设置位图或可绘制
- python - ModuleNotFoundError:没有名为“jqmcvi”的模块
- android - Android TV:回收站视图不滚动
- java - 为什么Java中没有删除成员字段的这种通用类型信息?