ES6 introduced Map and Set as specialized collection types. While we can do most things with plain objects and arrays, these have specific advantages that make them the better choice in certain situations.
Map
A Map is like an object, but with some important differences — it can have any type as a key (not just strings), it maintains insertion order, and it has a size property.
const map = new Map();
// Setting values — keys can be anything
map.set("name", "Manish");
map.set(42, "the answer");
map.set(true, "yes");
const objKey = { id: 1 };
map.set(objKey, "object as a key!");
// Getting values
map.get("name"); // "Manish"
map.get(42); // "the answer"
map.get(objKey); // "object as a key!"
// Other methods
map.has("name"); // true
map.delete(42); // removes the entry
map.size; // 3
map.clear(); // removes everything
Iterating over a Map
const userRoles = new Map([
["Manish", "admin"],
["Rahul", "editor"],
["Priya", "viewer"]
]);
for (const [name, role] of userRoles) {
console.log(`${name} is ${role}`);
}
userRoles.forEach((role, name) => {
console.log(`${name}: ${role}`);
});
Map vs Object — when to use which
| Feature | Map | Object |
|---|---|---|
| Key types | Any (object, number, boolean) | Strings and Symbols only |
| Order | Guaranteed insertion order | Not guaranteed (mostly works, but not spec’d for all cases) |
| Size | map.size | Object.keys(obj).length |
| Iteration | Directly iterable | Need Object.entries() |
| Performance | Better for frequent add/delete | Better for static structures |
| Prototype | No inherited keys | Has prototype keys |
Use Map when: keys aren’t strings, we need to frequently add/delete entries, we need the size, or we need guaranteed order.
Use Object when: keys are strings, the structure is mostly static (like config, JSON data), or we need JSON serialization.
Set
A Set is like an array, but every value must be unique. Duplicates are automatically ignored.
const set = new Set();
set.add(1);
set.add(2);
set.add(3);
set.add(2); // ignored — already exists
set.add(1); // ignored — already exists
console.log(set.size); // 3
console.log(set.has(2)); // true
set.delete(2);
console.log(set.size); // 2
Common use case: removing duplicates from an array
const numbers = [1, 2, 3, 2, 4, 1, 5, 3];
const unique = [...new Set(numbers)];
console.log(unique); // [1, 2, 3, 4, 5]
This one-liner is one of the most used Set patterns in real code.
Iterating over a Set
const tags = new Set(["javascript", "react", "node"]);
for (const tag of tags) {
console.log(tag);
}
tags.forEach(tag => console.log(tag));
WeakMap
A WeakMap is like a Map, but with two big restrictions:
- Keys must be objects (no primitives)
- Keys are weakly referenced — if nothing else references the key object, it gets garbage collected along with its value
const weakMap = new WeakMap();
let user = { name: "Manish" };
weakMap.set(user, "some metadata");
console.log(weakMap.get(user)); // "some metadata"
user = null; // the object can now be garbage collected
// The entry in weakMap is automatically cleaned up
WeakMaps are not iterable — we can’t loop over them or get their size. This is by design, because entries can disappear at any time due to garbage collection.
Use case: Storing private data or metadata associated with objects without preventing garbage collection. Common in frameworks for caching DOM node data.
WeakSet
Same idea as WeakMap, but for unique values:
- Values must be objects
- Weakly referenced — garbage collected when no other reference exists
- Not iterable, no size property
const weakSet = new WeakSet();
let obj = { id: 1 };
weakSet.add(obj);
weakSet.has(obj); // true
obj = null; // object can be garbage collected
Use case: Tracking which objects have been “seen” or processed, without preventing them from being garbage collected.
const visited = new WeakSet();
function processNode(node) {
if (visited.has(node)) return; // already processed
visited.add(node);
// ... process the node
}
Quick summary
- Map — object with any key type, ordered, has
.size. Use when keys aren’t strings or we need frequent add/delete. - Set — array with unique values only. Great for deduplication and membership checks.
- WeakMap — Map with object-only keys that don’t prevent garbage collection. Use for metadata/caching.
- WeakSet — Set with object-only values that don’t prevent garbage collection. Use for tracking objects.
In simple language, Map and Set fill the gaps that plain objects and arrays can’t cover well. Map for when we need non-string keys or care about size/order, Set for when we need unique values. The Weak variants are for when we want the garbage collector to clean up after us automatically.