JavaScript Map & Set Methods Reference
Map, Set, WeakMap, WeakSet — every method with syntax, time complexity, and examples — search and filter by collection
Browse by Collection
You need to deduplicate an array. You write [...new Set(arr)] — it works, but then you need the intersection of two sets and discover Set doesn’t have an intersection() method (until ES2025). Or you’re choosing between Map and a plain object for a cache and can’t remember the performance differences, or whether WeakMap is the right choice for DOM element metadata. The built-in collection types have enough overlap and subtle differences that a side-by-side comparison saves real debugging time.
Why This Reference (Not the Map Methods Reference or Set Methods Reference)
PureDevTools has separate Map Methods and Set Methods references for deep dives into each type. This reference covers all four collection types — Map, Set, WeakMap, WeakSet — side by side with comparison tables (Map vs Object, Set vs Array), time complexity, and the ES2025 Set methods. Use this for choosing between types; use the individual references for method details.
What This Reference Covers
JavaScript provides four built-in keyed collection types: Map, Set, WeakMap, and WeakSet. Each solves a distinct problem that plain objects and arrays cannot handle cleanly.
This reference documents every method and property for all four collections:
- Map — key-value pairs with any key type, ordered by insertion
- Set — unique values with O(1) lookup, ordered by insertion
- WeakMap — key-value pairs with object keys, garbage-collection-friendly
- WeakSet — a set of objects, garbage-collection-friendly
Every entry includes the syntax, parameters, return value, time complexity, and a copy-pasteable code example.
Map — Key-Value Pairs with Any Key Type
Map is a collection of keyed data items, similar to a plain object but with critical differences:
- Any value can be a key — objects, functions, numbers,
null,NaN,undefined - Insertion order is guaranteed — iterating always yields entries in the order they were added
- Size is accessible in O(1) via
map.size(no need to count keys) - No prototype pollution — no inherited keys like
toStringorconstructor
// Basic Map usage
const map = new Map();
map.set("name", "Alice");
map.set(42, "the answer");
map.set({ id: 1 }, "object key");
console.log(map.get("name")); // "Alice"
console.log(map.size); // 3
// Initialize from array of [key, value] pairs:
const m = new Map([
["a", 1],
["b", 2],
["c", 3],
]);
// Iterate:
for (const [key, value] of m) {
console.log(key, value);
}
Map vs Plain Object
| Feature | Map | Object |
|---|---|---|
| Key types | Any type | Strings and Symbols only |
| Key order | Insertion order | Numeric first, then insertion |
| Size | map.size — O(1) | Object.keys(obj).length — O(n) |
| Iteration | Directly iterable | Need Object.keys() / Object.entries() |
| Prototype keys | None | Inherited (toString, constructor…) |
| JSON support | Not native | JSON.stringify() / JSON.parse() |
When to use Map over Object:
- Keys are not strings (using DOM nodes, functions, or numbers as keys)
- You need to know the size quickly
- You frequently add and remove entries
- You iterate over entries regularly and need guaranteed insertion order
When to use Object over Map:
- Serializing to JSON directly (
JSON.stringifyworks on plain objects) - Modeling structured data with known property names
- Static configuration with string keys
Set — Unique Values with O(1) Lookup
Set is a collection of unique values. Adding a duplicate is silently ignored. Unlike arrays, membership checks are O(1) rather than O(n):
const set = new Set([1, 2, 2, 3, 3, 3]);
console.log([...set]); // [1, 2, 3] — duplicates removed
// O(1) membership check:
console.log(set.has(2)); // true
console.log(set.has(9)); // false
// Deduplicate an array — the most common Set use case:
const unique = [...new Set(someArray)];
// Set operations (union, intersection, difference):
const a = new Set([1, 2, 3, 4]);
const b = new Set([3, 4, 5, 6]);
const union = new Set([...a, ...b]); // {1,2,3,4,5,6}
const intersection = new Set([...a].filter(x => b.has(x))); // {3,4}
const difference = new Set([...a].filter(x => !b.has(x))); // {1,2}
Set vs Array
| Feature | Set | Array |
|---|---|---|
| Duplicates | Not allowed — automatic deduplication | Allowed |
| Membership check | O(1) — set.has(value) | O(n) — arr.includes(value) |
| Access by index | Not supported | arr[0], arr[arr.length - 1] |
| Remove element | O(1) — set.delete(value) | O(n) — arr.splice(arr.indexOf(v), 1) |
| Functional methods | Limited — forEach, for...of | Rich — map, filter, reduce, find |
When to use Set:
- You need unique values with no duplicates
- You need fast repeated membership checks (
Set.hasvsArray.includes) - Deduplicating an array:
[...new Set(array)] - Implementing union, intersection, or difference of value sets
When to use Array:
- You need access by numeric index
- You need
map(),filter(),reduce(),sort(), or other Array methods - Duplicate values are valid and expected
WeakMap — Private Data for Objects
WeakMap is like Map but with two key restrictions: keys must be objects (or registered Symbols), and the entries are weakly held. When a key object has no other references, the garbage collector can reclaim both the key and its entry — preventing memory leaks.
// Common pattern: attach private data to external objects
const _privateData = new WeakMap();
class Circle {
constructor(radius) {
_privateData.set(this, { radius });
}
get area() {
return Math.PI * _privateData.get(this).radius ** 2;
}
}
const c = new Circle(5);
console.log(c.area); // 78.53...
// When c is GC'd, _privateData automatically releases the entry
// DOM node metadata without memory leaks:
const nodeState = new WeakMap();
const button = document.querySelector("#btn");
nodeState.set(button, { clickCount: 0 });
// When button is removed from DOM and has no references,
// the nodeState entry is automatically cleaned up.
WeakMap has no size, no keys(), no values(), no entries(), no clear() — it is not enumerable. This is intentional: you cannot list all live keys because their liveness depends on the garbage collector.
WeakSet — Tracking Objects Without Memory Leaks
WeakSet is like Set but only stores objects (or registered Symbols), held weakly. It is not enumerable — you cannot iterate over the members or get its size.
// Cycle detection in recursive traversal:
function cloneDeep(value, seen = new WeakSet()) {
if (typeof value !== "object" || value === null) return value;
if (seen.has(value)) throw new Error("Circular reference detected");
seen.add(value);
return Array.isArray(value)
? value.map((v) => cloneDeep(v, seen))
: Object.fromEntries(
Object.entries(value).map(([k, v]) => [k, cloneDeep(v, seen)])
);
}
// Mark DOM nodes as initialized:
const initialized = new WeakSet();
function setupComponent(el) {
if (initialized.has(el)) return; // Already set up
// ... attach event listeners, inject content ...
initialized.add(el);
}
Time Complexity Quick Reference
All primary operations on Map, Set, WeakMap, and WeakSet run in O(1) average time:
| Operation | Map | Set | WeakMap | WeakSet |
|---|---|---|---|---|
| Add / Set | set() — O(1) | add() — O(1) | set() — O(1) | add() — O(1) |
| Lookup | get() / has() — O(1) | has() — O(1) | get() / has() — O(1) | has() — O(1) |
| Delete | delete() — O(1) | delete() — O(1) | delete() — O(1) | delete() — O(1) |
| Clear | clear() — O(n) | clear() — O(n) | Not available | Not available |
| Size | size — O(1) | size — O(1) | Not available | Not available |
| Iteration | O(n) | O(n) | Not available | Not available |
FAQ
Why does Map.prototype.forEach pass (value, key) instead of (key, value)?
Map.forEach matches the Array.forEach pattern where the element (value) comes before the position (key). This is a deliberate design choice for API consistency — the “item” comes first, the “locator” second. If you find the reversed order confusing, use for...of with destructuring: for (const [key, value] of map).
What is the difference between Map and WeakMap?
Map holds strong references to keys — as long as the Map exists, the keys are kept alive. WeakMap holds weak references — if a key object has no other references, it can be garbage-collected even while still in the WeakMap. WeakMap is also non-enumerable (no size, keys(), values(), entries(), forEach()). Use WeakMap when you want to associate data with objects without preventing those objects from being garbage-collected.
Can I use NaN as a Map or Set key?
Yes. Map and Set use the SameValueZero algorithm for equality, which treats NaN as equal to itself (unlike ===). So map.set(NaN, "value") followed by map.get(NaN) works correctly, and a Set will not add NaN twice.
How do I convert a Map to a plain object or JSON?
const map = new Map([["a", 1], ["b", 2]]);
// Map → Object (string keys only):
const obj = Object.fromEntries(map);
// Map → JSON string:
const json = JSON.stringify(Object.fromEntries(map));
// Object → Map:
const back = new Map(Object.entries(obj));
How do I perform set operations (union, intersection, difference) with Set?
const a = new Set([1, 2, 3]);
const b = new Set([2, 3, 4]);
// Union:
const union = new Set([...a, ...b]); // {1, 2, 3, 4}
// Intersection:
const inter = new Set([...a].filter(x => b.has(x))); // {2, 3}
// Difference (a minus b):
const diff = new Set([...a].filter(x => !b.has(x))); // {1}
Is my data private?
Yes. All processing happens entirely in your browser. No content is sent to any server.