WeakRef та finalizationregistry в JavaScript
WeakRef
WeakRef створює слабке посилання на об'єкт, яке не перешкоджає його збору сміття.
Чому WeakRef?
Звичайні посилання заважають збору сміття:
javascript
let obj = { data: "важливі дані" };
const ref = obj; // Сильне посилання — obj не може бути зібрано
obj = null; // Оригінальне посилання видалено
console.log(ref.data); // Все ще доступно — ref підтримує його в живихЗ WeakRef об'єкт може бути зібрано сміття:
javascript
let obj = { data: "важливі дані" };
const weakRef = new WeakRef(obj);
obj = null; // Оригінальне посилання видалено
// Об'єкт може бути зібрано сміття зараз!
const deref = weakRef.deref(); // Повертає об'єкт або undefined
if (deref) {
console.log(deref.data); // Об'єкт все ще живий
} else {
console.log("Об'єкт був зібраний сміття");
}Практичний випадок використання: Кеш
javascript
class WeakCache {
#cache = new Map();
get(key) {
const ref = this.#cache.get(key);
if (!ref) return undefined;
const value = ref.deref();
if (!value) {
this.#cache.delete(key); // Очищення застарілого запису
return undefined;
}
return value;
}
set(key, value) {
this.#cache.set(key, new WeakRef(value));
}
}FinalizationRegistry
FinalizationRegistry дозволяє вам зареєструвати callback, який викликається, коли об'єкт збирається сміття:
javascript
const registry = new FinalizationRegistry((heldValue) => {
console.log(`Об'єкт з ключем "${heldValue}" був зібраний сміття`);
// Очищення: закриття з'єднань, видалення з кешу тощо.
});
let obj = { data: "деякі дані" };
registry.register(obj, "my-object-key");
obj = null; // Зрештою: "Об'єкт з ключем "my-object-key" був зібраний сміття"Кеш з автоматичним очищенням
javascript
class SmartCache {
#cache = new Map();
#registry = new FinalizationRegistry((key) => {
this.#cache.delete(key);
console.log(`Запис кешу "${key}" очищено`);
});
set(key, value) {
this.#cache.set(key, new WeakRef(value));
this.#registry.register(value, key);
}
get(key) {
return this.#cache.get(key)?.deref();
}
}Важливі зауваження
| Аспект | Деталі |
|---|---|
| Час збору сміття | Не гарантовано — може статися негайно або ніколи |
deref() | Може повернути undefined в будь-який момент |
| Час виклику callback | Виклик FinalizationRegistry не є детермінованим |
| Випадки використання | Кеші, управління ресурсами, програми, чутливі до пам'яті |
| Уникати | Не покладайтеся на фіналізацію для критичної логіки |
Важливо:
WeakRef та FinalizationRegistry — це розширені функції для програм, чутливих до пам'яті. Поведінка збирача сміття є недетермінованою — ви не можете покладатися на те, коли (або чи) об'єкти будуть зібрані. Ці функції призначені для кешів та очищення ресурсів, а не для основної логіки програми.
Коротка відповідь
Для співбесідиPremium
Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.