Suggest an editImprove this articleRefine the answer for “What does WeakRef do?”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)`WeakRef` is an object that holds a weak reference to another object, meaning a reference that does not stop the garbage collector from removing that object once nothing else references it. **Key point:** `WeakRef` lets you "remember" an object while it is alive, without artificially keeping it in memory.Shown above the full answer for quick recall.Answer (EN)Image## What WeakRef is `WeakRef` **(Weak Reference)** is an object that holds a **weak reference to another object**, meaning a reference that **does not stop the garbage collector from removing that object** once nothing else references it. Put simply: > `WeakRef` lets you "remember" an object **while it is alive**, > without **artificially keeping it in memory**. ## Example of a regular (strong) reference ```javascript let user = { name: "Tim" }; let ref = user; // a regular reference user = null; // but ref still holds the object! console.log(ref.name); // "Tim" ``` The object **will not be removed by the garbage collector** as long as at least one "strong" reference (`ref`) exists. ## Example of a weak reference (WeakRef) ```javascript let user = { name: "Tim" }; let weakRef = new WeakRef(user); user = null; // now there are no strong references // ...later, maybe... console.log(weakRef.deref()?.name); // "Tim" or undefined ``` Now the object can be **removed by the GC at any moment**, and `weakRef.deref()` returns `undefined` if the object has already been collected. ## How WeakRef works 1. `new WeakRef(obj)` creates a weak reference. 2. `weakRef.deref()` tries to return the original object (if it's still alive). 3. If the object has already been collected by the GC, `deref()` returns `undefined`. ## An example of real behavior ```javascript let ref; (() => { let bigObject = { data: "Some heavy data..." }; ref = new WeakRef(bigObject); })(); // bigObject is no longer directly reachable setTimeout(() => { console.log(ref.deref()); // either the object or undefined - depends on the GC }, 1000); ``` The garbage collector runs at an **undetermined moment**. You cannot predict when `deref()` will start returning `undefined`. ## Why WeakRef is needed Normally in JS you **don't need** to worry about manual memory management. But there are narrow cases where `WeakRef` is useful: | Scenario | Example | |---|---| | **Caching without leaks** | You want to cache objects without holding them in memory "forever" | | **Memoization** | For example, storing a computation result for an object while it's alive | | **Reactive systems / observers** | Watching an object without blocking its collection | | **Game engines / graphics** | Caching heavy resources (textures, data) while letting the GC clean them up | | **Integration with FinalizationRegistry** | Reacting when an object gets collected by the GC | ## Example: a leak-free cache A regular Map holds keys strongly: ```javascript const cache = new Map(); function getUserData(user) { if (!cache.has(user)) { cache.set(user, heavyCompute(user)); } return cache.get(user); } ``` The problem: even if `user` is no longer needed, the `Map` **won't let the GC remove it** until the cache is cleared manually. The solution is to use `WeakRef` and `FinalizationRegistry`: ```javascript const cache = new Map(); function getUserData(user) { const ref = cache.get(user); let data = ref?.deref(); if (!data) { data = heavyCompute(user); cache.set(user, new WeakRef(data)); } return data; } ``` Now if `data` is no longer used anywhere else, the GC frees it, and `ref.deref()` simply returns `undefined`. ## Pairing with FinalizationRegistry To find out **when an object was collected by the GC**, you use `FinalizationRegistry`. ```javascript const registry = new FinalizationRegistry(id => { console.log(`Object ${id} removed from memory`); }); let user = { name: "Tim" }; registry.register(user, "user#1"); let ref = new WeakRef(user); user = null; ``` When the GC collects `user`, the callback fires: ```javascript Object user#1 removed from memory ``` (the call is not guaranteed to happen at any particular time and may not happen at all before the process ends.) ## Important to know | Feature | Description | |---|---| | `WeakRef` does not prevent collection | the object can disappear at any moment | | `deref()` can return `undefined` | if the GC has already removed the object | | You cannot "rely" on the object's lifetime | the GC is unpredictable | | Don't use it without a reason | it can lead to "zombie" bugs (the object suddenly disappears) | | Useful only in specific scenarios | caching, memoization, integration with the GC | ## When you should NOT use WeakRef For managing regular data. To "speed up" the GC - this is pointless. For storing state in React/Vue/Next. In critical logical chains (the result can disappear at any moment). ## Summary | What it does | Creates a weak reference to an object | |---|---| | How it works | Does not stop the GC from removing the object | | Method | `.deref()` returns the object or `undefined` | | Useful for | Caches, memoization, memory tracking | | Risks | The object can disappear at any moment | | Introduced in | ES2021 | **The main idea:** > `WeakRef` = "a reference that doesn't get in the garbage collector's way". > Use it when you want to *"hold an object without owning it"*.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.