WeakRef and finalizationregistry in JavaScript
WeakRef
A WeakRef creates a weak reference to an object that does not prevent it from being garbage collected.
Why WeakRef?
Normal references prevent garbage collection:
javascript
let obj = { data: "important" };
const ref = obj; // Strong reference — obj can't be GC'd
obj = null; // Original reference removed
console.log(ref.data); // Still accessible — ref keeps it aliveWith WeakRef, the object can be garbage collected:
javascript
let obj = { data: "important" };
const weakRef = new WeakRef(obj);
obj = null; // Original reference removed
// Object may be garbage collected now!
const deref = weakRef.deref(); // Returns object or undefined
if (deref) {
console.log(deref.data); // Object still alive
} else {
console.log("Object was garbage collected");
}Practical Use Case: Cache
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); // Clean up stale entry
return undefined;
}
return value;
}
set(key, value) {
this.#cache.set(key, new WeakRef(value));
}
}FinalizationRegistry
FinalizationRegistry lets you register a callback that's called when an object is garbage collected:
javascript
const registry = new FinalizationRegistry((heldValue) => {
console.log(`Object with key "${heldValue}" was garbage collected`);
// Cleanup: close connections, remove from cache, etc.
});
let obj = { data: "some data" };
registry.register(obj, "my-object-key");
obj = null; // Eventually: "Object with key "my-object-key" was garbage collected"Cache with Automatic Cleanup
javascript
class SmartCache {
#cache = new Map();
#registry = new FinalizationRegistry((key) => {
this.#cache.delete(key);
console.log(`Cache entry "${key}" cleaned up`);
});
set(key, value) {
this.#cache.set(key, new WeakRef(value));
this.#registry.register(value, key);
}
get(key) {
return this.#cache.get(key)?.deref();
}
}Important Caveats
| Aspect | Detail |
|---|---|
| GC timing | Not guaranteed — may happen immediately or never |
deref() | May return undefined at any point |
| Callback timing | FinalizationRegistry callback is not deterministic |
| Use cases | Caches, resource management, memory-sensitive apps |
| Avoid | Don't rely on finalization for critical logic |
Important:
WeakRef and FinalizationRegistry are advanced features for memory-sensitive applications. The garbage collector's behavior is non-deterministic — you cannot rely on when (or if) objects will be collected. These are meant for caches and resource cleanup, not core application logic.
Short Answer
Interview readyPremium
A concise answer to help you respond confidently on this topic during an interview.