Engrain by ByteRush

JS.06.02 Mid-level· 10 minCore — asked often

Map, Set, WeakMap and WeakRef: choosing the right collection

Map takes any key and keeps order; Set keeps unique values and now has union and intersection; WeakMap keys objects without keeping them alive.

Comes up in: JavaScript, Coding, DSA

Learn#

Rahul counts visits per user with a plain object: visits[user] = 1. Every user ends up under the same key, "[object Object]", because plain objects turn keys into strings.

A Map fixes that. Its keys can be any value — objects, numbers, functions — compared by identity. It keeps insertion order, has .size, and has no inherited keys like toString to collide with.

A Set holds unique values. Since ES2025 it also has union, intersection, difference and more.

const visits = new Map();
const user = { id: 7 };
visits.set(user, 3).set("guest", 1).set(42, 0);
console.log(visits.get(user), visits.size, [...visits.keys()].map(String));
const plain = {};
plain[user] = 3;
console.log(Object.keys(plain), "toString" in plain, visits.has("toString"));
const a = new Set([1, 2, 3, 3]), b = new Set([2, 3, 4]);
console.log(a.size, [...a.union(b)], [...a.intersection(b)], [...a.difference(b)]);

Output (verified)

3 3 [ '[object Object]', 'guest', '42' ]
[ '[object Object]' ] true false
3 [ 1, 2, 3, 4 ] [ 2, 3 ] [ 1 ]

A WeakMap only takes objects as keys and holds them by weak reference: the entry does not keep the key alive. When the object is gone, so is its entry. That makes WeakMaps right for caches and extra data attached to objects you do not own, like DOM nodes. In exchange, you cannot list or count their entries.

Map vs WeakMap for a DOM cacheStep 1 of 4

page

  • <div id=card>

Cache

  • card → layout data

cache (Map)

    empty

    cache (WeakMap)

      empty

      A Map cache keyed by DOM node: the map holds the node strongly.

      Read the steps as text
      1. A Map cache keyed by DOM node: the map holds the node strongly.
      2. The card is removed from the page. A Map still points to it, so it stays in memory.
      3. With a WeakMap, the entry does not keep the key alive.
      4. Nothing else references the card, so the garbage collector can free it — and the entry disappears.

      Predict#

      Predict first

      const m = new Map(); m.set({ id: 1 }, 'a'); What is m.get({ id: 1 })?

      Interview angle#

      Say it like this — about 30 seconds

      “I use a Map when keys are not plain strings, when I add and remove keys often, when I need the size or guaranteed insertion order, or when keys come from users — no prototype collisions. A Set is for unique values, and now has union, intersection and difference. A WeakMap takes object keys without keeping them alive, so it is ideal for caches or metadata attached to DOM nodes or objects I don’t own. It is not iterable, by design.”

      Stays on your device. Nothing is uploaded.
      Follow-up When would you use a Map instead of a plain object?
      Non-string keys, frequent adds and deletes, needing .size or order, or untrusted keys like __proto__. Objects remain best for fixed-shape records and JSON.
      Follow-up Why can't you iterate a WeakMap?
      Its entries can disappear whenever the garbage collector runs, so a listing would depend on GC timing — and could reveal it.
      Follow-up Should you use WeakRef to build a cache?
      Rarely. When a WeakRef is cleared depends on the engine and timing; MDN advises avoiding it where possible. A WeakMap or a size-limited LRU (JS.16.03) is more predictable.

      Practice#

      On your own

      Write dedupeBy with a Set, and rewrite makeNodeCache with a WeakMap — the starter’s object turns every key into "[object Object]".

      Done when

      • dedupeBy(users, (u) => u.email) keeps the first user per email, in order.
      • get(obj) calls compute once per object and returns separate results for different objects.
      • get(42) throws a TypeError (WeakMap keys must be objects).
      Your solution
      Ctrl/⌘ + Enter

      Remember#

      Try to answer each card before you open it. Then add them to your reviews.

      What happens to object keys on a plain object?

      They are turned into strings, like '[object Object]'.

      How does Map compare object keys?

      By identity (SameValueZero), not by content.

      What makes a WeakMap weak?

      Its entries do not keep their object keys alive.

      Name three ES2025 Set methods.

      union, intersection, difference (also symmetricDifference, isSubsetOf…).

      Go deeper

      Four layers. Stop at the one your interview needs; each ends with a quick check.

      The core ideaEvery round

      Map: any key, ordered, sized. Set: unique values. WeakMap/WeakSet: object keys held weakly, not iterable. Use objects for records, Map for dictionaries.

      Check yourself: Can a WeakMap key be a string?

      No. Keys must be objects (or non-registered symbols).

      How it works underneathSenior rounds

      Map and Set use SameValueZero, so NaN works as a key and +0/-0 are the same (JS.05.03). The ES2025 Set methods accept any “set-like” argument with size, has and keys Source: MDN: Set composition.

      Check yourself: Which equality does Map use for keys?

      SameValueZero.

      Edge cases and trapsWhere people slip

      WeakRef holds an object without keeping it alive; deref() returns it or undefined. FinalizationRegistry runs a callback after collection — maybe late, maybe never. Do not put essential logic in either Source: MDN: WeakRef — avoid where possible.

      Check yourself: Is a FinalizationRegistry callback guaranteed to run?

      No. It may run late or never.

      In productionStaff-level answers

      An unbounded Map cache is a memory leak with good intentions. Use WeakMap when entries should live as long as their object key, and an LRU with a size limit when keys are strings (JS.16.03). Convert to plain objects only at the JSON boundary: Object.fromEntries(map).

      Check yourself: Why might a Map-based cache grow forever?

      Entries are never evicted; it needs a size limit or WeakMap keys.

      Finished the five steps? Mark it, and its cards join your reviews.

      Last checked 2026-10-31. Spot a mistake? Use “Report an error” below — fixes are listed on the corrections page.

      Interview questions this answers

      • When would you use a Map instead of a plain object?
      • What is a WeakMap and when is it useful?