DEV Community

Cover image for WeakMap vs WeakSet: What They Are, When to Use, and How They Save Memory
Anisubhra Sarkar (Ani)
Anisubhra Sarkar (Ani)

Posted on

WeakMap vs WeakSet: What They Are, When to Use, and How They Save Memory

In modern applications, especially single-page apps and backend services, memory leaks can silently degrade performance over time. Two lesser-used but powerful structures in JavaScript — WeakMap and WeakSet — help solve memory management issues by letting the garbage collector automatically clean up unused references.

Let’s break down what they are, how they help prevent memory leaks, and real-world scenarios where you’d use them.


WeakMap

What It Is

  • A WeakMap is a collection of key–value pairs, where keys must be objects.
  • If the object key is no longer referenced anywhere else in the program, the entry is automatically garbage collected.

Real-World Use Cases

1. DOM Node Metadata (Frontend Apps)

Imagine you’re building a rich text editor in React. You need to attach metadata to DOM nodes (e.g., selection state, highlight ranges). If you use a regular Map, the metadata will stick around even after the DOM node is removed, causing a memory leak.

const metadata = new WeakMap();

function attachMetadata(domNode, info) {
  metadata.set(domNode, info);
}

function getMetadata(domNode) {
  return metadata.get(domNode);
}

// Example usage
const node = document.querySelector("#editor");
attachMetadata(node, { highlighted: true });

// If node is removed later, the metadata entry is auto-collected
Enter fullscreen mode Exit fullscreen mode

👉 With WeakMap, once node is removed from the DOM and not referenced elsewhere, its metadata is cleaned up automatically.


2. Private Data in Classes (Encapsulation)

If you’re writing a UI component library, you may want to keep internal data private. Using WeakMap, you can associate private state with an object instance without exposing it.

const _state = new WeakMap();

class Tooltip {
  constructor(text) {
    _state.set(this, { text, visible: false });
  }

  show() {
    _state.get(this).visible = true;
  }

  hide() {
    _state.get(this).visible = false;
  }
}

const t = new Tooltip("Hello");
t.show();
// When `t` is garbage collected, its state is gone automatically
Enter fullscreen mode Exit fullscreen mode

👉 This pattern prevents leaks since _state only keeps data as long as the instance exists.


WeakSet

What It Is

  • A WeakSet is a collection of objects only (no primitives).
  • Like WeakMap, objects are held weakly, so they don’t prevent garbage collection.

Real-World Use Cases

1. Tracking DOM Nodes That Need Special Handling

Say you’re building an infinite scroll feature and want to keep track of which elements have already been lazy-loaded.

const loadedElements = new WeakSet();

function handleScroll(element) {
  if (!loadedElements.has(element)) {
    // Load content for this element
    console.log("Loading content for", element.id);

    loadedElements.add(element);
  }
}

// Example
const section = document.querySelector("#feed");
handleScroll(section);

// If section is removed, garbage collection takes care of it
Enter fullscreen mode Exit fullscreen mode

👉 WeakSet ensures that once the DOM node is removed, it doesn’t linger in memory.


2. Preventing Double-Processing of Objects (Backend/Frontend)

In a backend service (Node.js), you might process request objects in middleware. You want to ensure the same request object isn’t processed twice.

const processedRequests = new WeakSet();

function processRequest(req) {
  if (processedRequests.has(req)) {
    return; // Already processed
  }

  // Do expensive processing...
  processedRequests.add(req);
}
Enter fullscreen mode Exit fullscreen mode

👉 Since requests are short-lived, WeakSet prevents them from being retained after the request lifecycle ends.


When to Use WeakMap vs WeakSet

Use Case Choose
Associate metadata or hidden state with an object WeakMap
Store private data for class instances WeakMap
Avoid memory leaks when attaching data to DOM nodes WeakMap
Keep track of whether an object has been processed WeakSet
Mark objects as “done” without extra properties WeakSet
Manage sets of DOM nodes for lazy loading, animations, observers WeakSet

How They Prevent Memory Leaks

Normally, if you use a Map or Set, the references inside prevent garbage collection, even if the object is removed from your app. This creates a memory leak.

With WeakMap and WeakSet:

  • Keys/values tied to unreferenced objects are automatically cleared.
  • No need to manually clean up.

Final Thoughts

  • Use WeakMap when you need extra data associated with objects (like metadata or private state).
  • Use WeakSet when you only need to mark or track objects without storing extra data.
  • Both help ensure your application doesn’t leak memory, especially in cases involving DOM elements, requests, or component lifecycles.

👉 Think of them as tools for ephemeral associations — data that should exist only as long as the object itself lives.

Top comments (0)