Skip to content

JavaScript Tutorial Map, Set and Other Collections

WeakMap and WeakSet

Lesson 188 of 258 2 min read By Deepak Paswan Updated Oct 4, 2026

WeakMap and WeakSet are special versions of Map and Set. You will not need them often, but they solve a real problem: memory leaks from collections that keep objects alive.

The problem

A normal Map or Set holds a strong reference to its keys. As long as an object is a key, the garbage collector cannot free it, even if nothing else uses it.

script.js
JS
const cache = new Map();

function process(element) {
  cache.set(element, expensiveResult(element));
}
// If the element is removed from the page, the Map STILL holds it. Memory is never freed.

Weak references

A WeakMap holds its keys weakly. If the key object is not used anywhere else, it can be garbage collected, and its entry disappears automatically.

script.js
JS
const metadata = new WeakMap();

let user = { name: "Maya" };
metadata.set(user, { visits: 3 });

console.log(metadata.get(user));  // → { visits: 3 }
console.log(metadata.has(user));  // → true

user = null;   // nothing refers to the object now: it can be collected, and so can its entry

The rules

WeakMapWeakSet
Keys / valuesobjects only (and non-registered symbols)objects only
Methodsget, set, has, deleteadd, has, delete
Iteration / size / clearnot availablenot available

You cannot loop over them or ask how many entries they hold, because the garbage collector may remove entries at any time, and the result would be unpredictable.

Practical uses

1. Attach data to objects without changing them.

script.js
JS
const clickCounts = new WeakMap();

function recordClick(element) {
  clickCounts.set(element, (clickCounts.get(element) ?? 0) + 1);
}

const button = {};
recordClick(button);
recordClick(button);
console.log(clickCounts.get(button)); // → 2

When the element goes away, so does its count.

2. A cache keyed by objects.

script.js
JS
const cache = new WeakMap();

function areaOf(shape) {
  if (cache.has(shape)) return cache.get(shape);
  const area = shape.width * shape.height;
  cache.set(shape, area);
  return area;
}

const rect = { width: 3, height: 4 };
console.log(areaOf(rect)); // → 12
console.log(areaOf(rect)); // → 12 (cached)

3. Marking objects as processed (WeakSet).

script.js
JS
const seen = new WeakSet();

function once(obj) {
  if (seen.has(obj)) return "already handled";
  seen.add(obj);
  return "handled now";
}

const item = {};
console.log(once(item)); // → handled now
console.log(once(item)); // → already handled

4. Private data in older code, before #private fields existed. See Private Fields.

Do not rely on cleanup timing

You cannot observe exactly when an entry is removed, and JavaScript gives no guarantee about when garbage collection runs. Treat weak collections as a way to avoid leaks, not as a timer.

When not to use them

If you need to list the entries or count them, use Map or Set. If your keys are strings or numbers, weak collections do not apply at all.

lightbulb
The one-line summary
WeakMap and WeakSet let you associate data with objects without keeping those objects alive. If that sentence does not match a problem you have, you probably do not need them yet.