我的应用加载参考数据的实例。某些实例具有使用来自其他参考数据的数据的 getter。喜欢这个:
class Person{
name: string
cityId: number
get city(): City {
return City.all.get(this.cityId)!
}
}
由于参考数据永远不会改变,因此对 getter 的调用将始终返回相同的结果。所以我想做一个用结果代替自己的getter。我在想这样的装饰器:
export const selfReplacing = <T>(target: T, propertyKey: keyof T, descriptor: PropertyDescriptor): any => {
const oldGetter = descriptor.get!
descriptor.get = function (this: T) {
const value = oldGetter.call(this)
Object.defineProperty(this, propertyKey, {
value,
enumerable: true
})
return value
}
}
我可以像这样使用:
class Person{
name: string
cityId: number
@selfReplacing
get city(): City {
return City.all.get(this.cityId)!
}
}
这是最好的方法吗?
在第一次属性访问时重新定义属性描述符是执行此操作的最佳方法。
或者,可以将值缓存到局部变量,或者更好的是缓存到属性:
export const selfReplacing = <T>(target: T, propertyKey: keyof T, descriptor: PropertyDescriptor): any => {
const oldGetter = descriptor.get!
const cacheKey = Symbol(`${propertyKey} cache`);
descriptor.get = function (this: T) {
if (!(cacheKey in this))
this[cacheKey] = oldGetter.call(this);
return return this[cacheKey];
}
}
如果应该额外实现某些缓存策略(缓存过期等(,可能会有所帮助。