如何使用 JavaScript/TypeScript 在 class 代理处理程序中获取 属性 描述符
How do I obtain a property descriptor inside of a class proxy handler using JavaScript/TypeScript
使用 class 代理,我想在执行特定操作之前询问 属性 描述符;如果它是访问器,则做一件事;如果它是方法,则做另一件事;如果是 属性,则做第三件事。但问题是我不认为我正在寻找该功能的正确所有者:
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)
}
}
我认为没有从超级 class 拦截实例属性的实用方法,所以我放弃了。对于我的特定用例,足以防止首先通过 Object.freeze
:
定义 public 属性
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"
使用 class 代理,我想在执行特定操作之前询问 属性 描述符;如果它是访问器,则做一件事;如果它是方法,则做另一件事;如果是 属性,则做第三件事。但问题是我不认为我正在寻找该功能的正确所有者:
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)
}
}
我认为没有从超级 class 拦截实例属性的实用方法,所以我放弃了。对于我的特定用例,足以防止首先通过 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"