JavaScript · Advanced

WeakMap and WeakSet

WeakMap and WeakSet are like Map and Set, but they don’t keep their keys alive. When an object is no longer used elsewhere, it can be cleaned up automatically.

Advanced 5 min Lesson 42 of 49 Runnable examples
Before you start:Map and Set
0/49 in JavaScript
On this page · 5 min · Advanced

Learning objectives#

  • Explain what “weak” means
  • Store private data per object with WeakMap
  • Track objects with WeakSet
  • Know their restrictions

Explanation#

A normal Map holds strong references: as long as the Map exists, its keys can never be garbage-collected.

WeakMap and WeakSet hold weak references: if nothing else references the key object, the entry disappears automatically.

Keys must be objects (not strings or numbers), and they are not iterable — you cannot list their contents or get a size.

Typical uses: attaching private or cached data to DOM elements or objects without causing memory leaks.

Code example: Private data and visited tracking#

JavaScriptPrivate data and visited tracking Runnable
const privateData = new WeakMap();
class Counter {
  constructor() { privateData.set(this, { count: 0 }); }
  increment() {
    privateData.get(this).count++;
    return privateData.get(this).count;
  }
}
const c = new Counter();
c.increment();
console.log(c.increment());
console.log(Object.keys(c).length);    // nothing visible on the object


const visited = new WeakSet();
const nodeA = { id: 'A' };
visited.add(nodeA);
console.log(visited.has(nodeA), visited.has({ id: 'A' }));


try { new WeakMap().set('key', 1); } catch (e) { console.log(e.name); }
Expected output
2
0
true false
TypeError
Opens this example in the full playground

Step-by-step explanation#

  1. Each Counter’s data is stored in the WeakMap, keyed by the instance itself.
  2. The object has no visible properties, so the data is effectively private.
  3. WeakSet.has checks identity — a different object with the same content is not found.
  4. Using a string key throws a TypeError: keys must be objects.
  5. When c is no longer referenced, its WeakMap entry can be collected automatically.

Real-world use case#

Libraries attach metadata to DOM nodes (for example, “this element has been initialised”) without leaking memory when nodes are removed.

Common mistakes#

Using primitive keys

Strings and numbers cannot be WeakMap keys.

Trying to iterate

WeakMap and WeakSet have no forEach, keys() or size, by design.

Best practices#

  • Use WeakMap for per-object caches and metadata
  • Prefer #private fields for class privacy in new code
  • Use WeakSet to mark objects as processed
  • Use Map/Set when you need to list or count entries

Remember this#

Weak = “don’t keep this object alive just for me”.

Keys must be objects. No size, no looping.

Perfect for caches and metadata without leaks.

Practice exercise#

Your task: Use a WeakSet to make a function process(obj) that only processes each object once.

Show solution
JavaScript Runnable
const done = new WeakSet();
function process(obj) {
  if (done.has(obj)) return 'skipped';
  done.add(obj);
  return 'processed';
}
const o = {};
console.log(process(o), process(o)); // processed skipped
Opens this example in the full playground

Mini quiz#

WeakMap and WeakSet quizMultiple choice Question 1 of 1

Which can be a WeakMap key?

Score so far: 0/0

Want more? Practise all JavaScript MCQs · JavaScript interview questions

My notes#

Saved in this browser.

Progress is saved in this browser. Sign in to sync.