“快取” getter 的做法是一種只呼叫一次值并重用相同值而不重新計算的方法。我正在尋找快取 getter 的“最佳”方法,最好的意思是使用最短的語法和打字。那里有許多庫只允許您使用像@cachegetter 這樣的裝飾器,它的行為方式與我描述的方式相同,我不打算使用裝飾器。
打字稿游樂場
這是一種方法:
type NoUndefined<T> = T extends undefined ? never : T;
function isNoUndefined <T> (value: T): value is NoUndefined<T> {
return typeof value !== 'undefined'
}
function handleGetter <T>(value:T, operation: () => NoUndefined<T>): NoUndefined<T> {
if (isNoUndefined(value)) return value;
return operation()
}
class CalendarDate extends Date {
#day: number | undefined = undefined
get day () {
return this.#day = handleGetter(this.#day, () => {
console.log('runs once')
return this.getDate()
})
}
}
const c = new CalendarDate()
c.day
c.day
c.day
c.day
uj5u.com熱心網友回復:
一種可能的方法是撰寫一個函式,將現有類原型中的 getter 替換為用智能/自覆寫/惰性 getter包裝的新函式:
function cacheGetter<T>(ctor: { prototype: T }, prop: keyof T): void {
const desc = Object.getOwnPropertyDescriptor(ctor.prototype, prop);
if (!desc) throw new Error("OH NO, NO PROPERTY DESCRIPTOR");
const getter = desc.get;
if (!getter) throw new Error("OH NO, NOT A GETTER");
Object.defineProperty(ctor.prototype, prop, {
get() {
const ret = getter.call(this);
Object.defineProperty(this, prop, { value: ret });
return ret;
}
})
}
因此,如果您呼叫cacheGetter(Clazz, "key"),它將獲取 的屬性描述符,Clazz.prototype.key并確保它有一個 getter。如果任一步驟失敗,則會引發錯誤。否則,它會創建一個新的 getter,當被呼叫時,它會在當前實體(而不是原型)上呼叫一次原始 getter,然后將實體上的屬性(同樣,不是原型)直接定義為快取值。所以下次在實體上訪問屬性時,它使用實體快取值而不是繼承的 getter。
讓我們測驗一下。在宣告類后應用它:
class CalendarDate extends Date {
get day() {
console.log('runs once');
return this.getDate();
}
}
cacheGetter(CalendarDate, "day"); // <-- here
并確保它按預期作業:
const c = new CalendarDate()
console.log(c.day); // runs once, 25
console.log(c.day); // 25
console.log(c.day); // 25
console.log(c.day); // 25
const d = new CalendarDate();
d.setDate(10);
console.log(d.day) // runs once, 10
console.log(c.day) // 25
console.log(d.day) // 10
看起來不錯。
因此,如果您不想使用裝飾器,這是我能為用戶想到的最短方法。我假設裝飾器方法將以類似的方式實作,作為屬性描述符的包裝器。
Playground 代碼鏈接
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/521499.html
標籤:打字稿班级缓存吸气剂
上一篇:在不使用條件的情況下根據$variable值實體化特定的類物件
下一篇:如何使用類獲取實體的值?
