LearnFrenzy
Sign in Take a free test

Modules, Map, Set and Generators · Lesson 32 of 40

Map, Set, WeakMap and Symbol

5 min read Updated Nov 7, 2026 Saurabh Samir

Objects and arrays can do almost anything, but they aren't always the right tool. Map is a proper key-value dictionary; Set is a collection of unique values. They're faster and safer for those jobs, and knowing when to reach for them is a sign of an experienced developer.

In this lesson

  • Map: any key type, insertion order, size
  • Set: unique values and set operations
  • WeakMap and WeakSet for attaching data to objects
  • Symbols as unique keys

Map

const stock = new Map();
stock.set("pen", 120).set("notebook", 45).set("bag", 0);    // set() is chainable

console.log(stock.get("pen"), stock.has("bag"), stock.size);
stock.delete("bag");
console.log([...stock.keys()]);

for (const [item, qty] of stock) {
  console.log(`${item}: ${qty}`);
}

const prices = new Map(Object.entries({ pen: 20, notebook: 60 }));   // object → Map
console.log(Object.fromEntries(prices));                             // Map → object

Output

120 true 3
[ 'pen', 'notebook' ]
pen: 120
notebook: 45
{ pen: 20, notebook: 60 }

Any value can be a key

const asha = { id: 1, name: "Asha" };
const ravi = { id: 2, name: "Ravi" };

const lastSeen = new Map();
lastSeen.set(asha, "10:42").set(ravi, "09:15");
console.log(lastSeen.get(asha));

const obj = {};
obj[asha] = "10:42";               // an object key is converted to a string…
obj[ravi] = "09:15";               // …so both become "[object Object]"
console.log(Object.keys(obj), obj[asha]);

Output

10:42
[ '[object Object]' ] 09:15
ObjectMap
Key typesstrings and symbolsanything – objects, functions, numbers
Orderinsertion, but integer keys firstalways insertion order
SizeObject.keys(o).lengthmap.size
Inherited keysyes (e.g. "toString", "__proto__")none
Frequent add/removesloweroptimised for it
JSONdirectconvert with Object.fromEntries or [...map]
Best forfixed-shape records (a user, a config)dictionaries, caches, lookups by ID

Set

const visitors = new Set();
for (const id of [101, 205, 101, 330, 205]) visitors.add(id);    // duplicates ignored
console.log(visitors.size, visitors.has(330), [...visitors]);

const tags = new Set(["js", "sql", "js", "react"]);
tags.delete("sql");
console.log(tags);

Output

3 true [ 101, 205, 330 ]
Set(2) { 'js', 'react' }

set.has(x) is close to O(1); array.includes(x) is O(n). For large lists you check often, a Set is dramatically faster.

Set operations

const javaDevs = new Set(["Asha", "Ravi", "Meera"]);
const jsDevs = new Set(["Ravi", "Meera", "Kiran"]);

const both = javaDevs.intersection(jsDevs);
const either = javaDevs.union(jsDevs);
const onlyJava = javaDevs.difference(jsDevs);
console.log([...both], [...either], [...onlyJava]);
console.log(new Set(["Ravi"]).isSubsetOf(jsDevs));

// The same without the newer methods (works everywhere):
const bothManual = [...javaDevs].filter((d) => jsDevs.has(d));
console.log(bothManual);

Output

[ 'Ravi', 'Meera' ] [ 'Asha', 'Ravi', 'Meera', 'Kiran' ] [ 'Asha' ]
true
[ 'Ravi', 'Meera' ]

Set methods (ES2025)

  • unionin either
  • intersectionin both
  • differencein A, not B
  • symmetricDifferencein exactly one
  • isSubsetOfall of A in B?
  • isDisjointFromnothing shared?

WeakMap and WeakSet

A WeakMap holds its object keys "weakly": when nothing else references the key object, it (and its value) can be garbage-collected. That makes WeakMap ideal for attaching extra data to objects you don't own – DOM elements, objects from a library – without causing memory leaks.

const clickCounts = new WeakMap();
function trackClick(element) {
  clickCounts.set(element, (clickCounts.get(element) ?? 0) + 1);
  return clickCounts.get(element);
}
const button = { id: "buy" };          // stands in for a DOM element
trackClick(button);
console.log(trackClick(button));
// When the button is removed and no longer referenced, its entry disappears automatically.

Output

2

WeakMap keys must be objects, and a WeakMap can't be looped over or sized – by design, since entries may vanish at any time. WeakSet is the same idea for "has this object been seen?" checks.

Symbols

A Symbol is a unique, primitive value. Two symbols are never equal, even with the same description, which makes them perfect as property keys that can't clash with anyone else's:

const id = Symbol("id");
const user = { name: "Asha", [id]: 9001 };
console.log(user[id], Symbol("id") === Symbol("id"));
console.log(Object.keys(user), JSON.stringify(user));    // symbol keys are hidden

// Well-known symbols customise built-in behaviour
const range = {
  from: 1, to: 4,
  [Symbol.iterator]: function* () { for (let i = this.from; i <= this.to; i++) yield i; },
};
console.log([...range]);

Output

9001 false
[ 'name' ] {"name":"Asha"}
[ 1, 2, 3, 4 ]

Symbol.iterator is how for...of and spread work – the next lesson builds on it.

Practice

Try it yourself

  1. Find the first repeated character in "programming" using a Set.

    Show solution
    function firstRepeat(str) {
      const seen = new Set();
      for (const ch of str) {
        if (seen.has(ch)) return ch;
        seen.add(ch);
      }
      return null;
    }
    console.log(firstRepeat("programming"), firstRepeat("abc"));

    Output

    r null
  2. Count word frequency with a Map and print the most common word.

    Show solution
    const words = "the cat and the hat and the bat".split(" ");
    const freq = new Map();
    for (const w of words) freq.set(w, (freq.get(w) ?? 0) + 1);
    const [top, count] = [...freq].reduce((best, e) => (e[1] > best[1] ? e : best));
    console.log(top, count);

    Output

    the 3

Quick check

When should you choose a Map over an object?

For dictionaries with dynamic or non-string keys, frequent additions/removals, or when you need size and guaranteed order.

How do you remove duplicates from an array?

[...new Set(arr)]

Why can't you loop over a WeakMap?

Its entries can be garbage-collected at any moment, so enumeration would be unreliable.

Summary

  • Map: any key type, insertion order, size – best for dictionaries and caches.
  • Set: unique values, fast has, and union/intersection/difference.
  • WeakMap attaches data to objects without leaks; Symbols create clash-free keys.

Finished this lesson?

Mark it complete to track your progress, then carry on with the next lesson.

Next lesson

Popular