JavaScript 37 🧬 Maps
const map = new Map();
map.set('name', 'Alice');
map.set('age', 30);
map.set(1, 'one');
console.log(map.get('name'));
console.log(map.has('age'));
console.log(map.size);
map.delete('age');
console.log(map.size);
map.clear();
console.log(map.size);
const map2 = new Map([
['a', 1],
['b', 2],
['c', 3]
]);
for (const [key, value] of map2) {
console.log(key, value);
}
A Map is JavaScript’s dedicated key-value data structure. Unlike plain objects, a Map can use any value as a key — objects, functions, numbers, even other maps — and it preserves insertion order for iteration. It’s the modern replacement for using objects as dictionaries.
Key point: Use Map when your keys aren’t strings, when you need to know the size, when you iterate often, or when you want a clean API for adding and removing entries. Use plain objects when you’re modeling a fixed record with named fields.
a – What is a Map and when to use it
A Map is a collection of key-value pairs where both keys and values can be of any type. It’s built into the language — no import needed.
Creating a Map:
const map = new Map();
You can also initialize a Map from an array of [key, value] pairs:
const map2 = new Map([
['a', 1],
['b', 2],
['c', 3]
]);
Map vs Object — the key differences:
| Feature | Map | Object |
|---|---|---|
| Key types | Any value | Strings and symbols only |
| Size | map.size | Object.keys(obj).length |
| Iteration | Directly iterable | Needs Object.keys/values/entries |
| Insertion order | Guaranteed | Mostly, but not for numeric-like keys |
| Prototype keys | None — clean | Inherits from Object.prototype |
Key collision with __proto__ | No | Yes |
| JSON | Not directly | JSON.stringify works |
| Performance for frequent add/remove | Better | Worse |
When to use a Map:
- Keys are not strings — numbers, objects, functions
- You add and remove keys frequently
- You need the size without counting
- You iterate often
- You want no prototype pollution risk
When to use an Object:
- You’re modeling a fixed record —
{ name, age, city } - You need JSON serialization directly
- Keys are always strings and known upfront
- You want dot notation for readability
The classic Map use case — counting:
const words = ['apple', 'banana', 'apple', 'cherry', 'banana', 'apple'];
const counts = new Map();
for (const word of words) {
counts.set(word, (counts.get(word) || 0) + 1);
}
console.log(counts);
// Map(3) { 'apple' => 3, 'banana' => 2, 'cherry' => 1 }
With a plain object, you’d have to worry about inherited keys and couldn’t use non-string keys.
Why Maps matter:
- Predictable iteration order — entries come out in the order they were added
- Clean API —
set,get,has,delete,clear,size - Any key type — objects and functions as keys
- No collisions — no inherited properties to worry about
- Efficient — optimized for frequent changes
b – Map methods and properties
A Map has a small, focused API. Every method has a clear purpose.
Core methods:
| Method | Purpose |
|---|---|
set(key, value) | Add or update an entry |
get(key) | Retrieve a value by key |
has(key) | Check if a key exists |
delete(key) | Remove an entry |
clear() | Remove all entries |
size | Number of entries (property) |
Iteration methods:
| Method | Purpose |
|---|---|
keys() | Iterator over keys |
values() | Iterator over values |
entries() | Iterator over [key, value] pairs |
forEach(callback) | Loop with a callback |
set — add or update:
const map = new Map();
map.set('name', 'Alice');
map.set('age', 30);
map.set(1, 'one');
console.log(map);
// Map(3) { 'name' => 'Alice', 'age' => 30, 1 => 'one' }
Calling set on an existing key updates the value:
map.set('age', 31);
console.log(map.get('age'));
// 31
set returns the map itself, so you can chain:
map.set('a', 1).set('b', 2).set('c', 3);
get — retrieve a value:
console.log(map.get('name'));
// Alice
console.log(map.get('missing'));
// undefined
get returns undefined for missing keys — it does not throw.
has — check existence:
console.log(map.has('age'));
// true
console.log(map.has('city'));
// false
Always use has before get when undefined could be a valid value:
const map = new Map([['key', undefined]]);
console.log(map.get('key'));
// undefined
console.log(map.has('key'));
// true — the key exists, its value is undefined
delete — remove an entry:
map.delete('age');
console.log(map.has('age'));
// false
delete returns true if the key existed, false otherwise:
console.log(map.delete('name'));
// true
console.log(map.delete('name'));
// false
clear — remove everything:
map.clear();
console.log(map.size);
// 0
size — count entries:
const map = new Map([['a', 1], ['b', 2], ['c', 3]]);
console.log(map.size);
// 3
size is a property, not a method — no parentheses.
keys(), values(), entries():
const map = new Map([['a', 1], ['b', 2], ['c', 3]]);
console.log([...map.keys()]);
// [ 'a', 'b', 'c' ]
console.log([...map.values()]);
// [ 1, 2, 3 ]
console.log([...map.entries()]);
// [ [ 'a', 1 ], [ 'b', 2 ], [ 'c', 3 ] ]
Each returns an iterator, not an array — spread it or use for...of to consume it.
forEach — callback iteration:
map.forEach((value, key) => {
console.log(`${key}: ${value}`);
});
// a: 1
// b: 2
// c: 3
Note the argument order: value first, then key. This is the opposite of what most people expect.
Iterating with for...of:
for (const [key, value] of map) {
console.log(key, value);
}
// a 1
// b 2
// c 3
Destructuring [key, value] from each entry is the idiomatic way.
Iterating keys only:
for (const key of map.keys()) {
console.log(key);
}
Iterating values only:
for (const value of map.values()) {
console.log(value);
}
Complete example:
const map = new Map();
map.set('name', 'Alice');
map.set('age', 30);
map.set(1, 'one');
console.log(map.get('name')); // Alice
console.log(map.has('age')); // true
console.log(map.size); // 3
map.delete('age');
console.log(map.size); // 2
map.clear();
console.log(map.size); // 0
const map2 = new Map([
['a', 1],
['b', 2],
['c', 3]
]);
for (const [key, value] of map2) {
console.log(key, value);
}
// a 1
// b 2
// c 3
c – Common Map patterns
Maps shine in a handful of recurring patterns. Learn these and you’ll reach for a Map instinctively.
Pattern 1 — Counting occurrences:
const votes = ['alice', 'bob', 'alice', 'charlie', 'bob', 'alice'];
const tally = new Map();
for (const vote of votes) {
tally.set(vote, (tally.get(vote) || 0) + 1);
}
console.log(tally);
// Map(3) { 'alice' => 3, 'bob' => 2, 'charlie' => 1 }
The (map.get(k) || 0) + 1 idiom is the standard counting pattern.
Pattern 2 — Grouping items:
const people = [
{ name: 'Alice', dept: 'Eng' },
{ name: 'Bob', dept: 'Sales' },
{ name: 'Charlie', dept: 'Eng' },
{ name: 'Dana', dept: 'Sales' }
];
const byDept = new Map();
for (const person of people) {
if (!byDept.has(person.dept)) {
byDept.set(person.dept, []);
}
byDept.get(person.dept).push(person.name);
}
console.log(byDept);
// Map(2) {
// 'Eng' => [ 'Alice', 'Charlie' ],
// 'Sales' => [ 'Bob', 'Dana' ]
// }
Pattern 3 — Caching / memoization:
const cache = new Map();
function slowSquare(n) {
if (cache.has(n)) {
return cache.get(n);
}
const result = n * n;
cache.set(n, result);
return result;
}
console.log(slowSquare(5)); // 25 (computed)
console.log(slowSquare(5)); // 25 (from cache)
Pattern 4 — Using objects as keys:
const obj1 = { id: 1 };
const obj2 = { id: 2 };
const map = new Map();
map.set(obj1, 'first');
map.set(obj2, 'second');
console.log(map.get(obj1)); // first
console.log(map.get(obj2)); // second
// Two different objects are different keys
console.log(map.get({ id: 1 })); // undefined
This is impossible with plain objects — they stringify keys.
Pattern 5 — Tracking metadata per object:
const elements = [document.body, document.head];
const meta = new Map();
elements.forEach((el, i) => {
meta.set(el, { index: i, tag: el.tagName });
});
console.log(meta.get(document.body));
// { index: 0, tag: 'BODY' }
Pattern 6 — Converting between Map and Object:
Map → Object:
const map = new Map([['a', 1], ['b', 2]]);
const obj = Object.fromEntries(map);
console.log(obj);
// { a: 1, b: 2 }
Object → Map:
const obj = { a: 1, b: 2 };
const map = new Map(Object.entries(obj));
console.log(map);
// Map(2) { 'a' => 1, 'b' => 2 }
Pattern 7 — Converting between Map and Array:
const map = new Map([['a', 1], ['b', 2]]);
// Map → array of entries
const entries = [...map];
console.log(entries);
// [ [ 'a', 1 ], [ 'b', 2 ] ]
// Array → Map
const back = new Map(entries);
Pattern 8 — Merging Maps:
const m1 = new Map([['a', 1], ['b', 2]]);
const m2 = new Map([['b', 99], ['c', 3]]);
const merged = new Map([...m1, ...m2]);
console.log(merged);
// Map(3) { 'a' => 1, 'b' => 99, 'c' => 3 }
Later entries override earlier ones.
Pattern 9 — Filtering a Map:
const map = new Map([['a', 1], ['b', 2], ['c', 3]]);
const filtered = new Map([...map].filter(([k, v]) => v > 1));
console.log(filtered);
// Map(2) { 'b' => 2, 'c' => 3 }
Pattern 10 — WeakMap for object keys:
const wm = new WeakMap();
let key = { id: 1 };
wm.set(key, 'value');
console.log(wm.get(key));
// value
key = null; // the WeakMap entry is garbage collected
WeakMap only accepts objects as keys and doesn’t prevent garbage collection. Use it when you want to attach data to objects without leaking memory.
Map vs WeakMap:
| Feature | Map | WeakMap |
|---|---|---|
| Key types | Any | Objects only |
| Size | map.size | Not available |
| Iteration | Yes | No |
| Garbage collection | Keys held strongly | Keys held weakly |
| Use case | General purpose | Metadata attached to objects |
Complete Example Session
// ============================================
// PART 1: CREATING A MAP
// ============================================
const map = new Map();
console.log(map.size);
// [ 0 ]
// ============================================
// PART 2: SETTING VALUES
// ============================================
map.set('name', 'Alice');
map.set('age', 30);
map.set(1, 'one');
console.log(map);
// [ Map(3) { 'name' => 'Alice', 'age' => 30, 1 => 'one' } ]
// ============================================
// PART 3: GETTING VALUES
// ============================================
console.log(map.get('name'));
// [ Alice ]
console.log(map.get(1));
// [ one ]
console.log(map.get('missing'));
// [ undefined ]
// ============================================
// PART 4: CHECKING EXISTENCE
// ============================================
console.log(map.has('age'));
// [ true ]
console.log(map.has('city'));
// [ false ]
// ============================================
// PART 5: SIZE
// ============================================
console.log(map.size);
// [ 3 ]
// ============================================
// PART 6: DELETING
// ============================================
map.delete('age');
console.log(map.size);
// [ 2 ]
console.log(map.delete('age'));
// [ false ]
// ============================================
// PART 7: CLEARING
// ============================================
map.clear();
console.log(map.size);
// [ 0 ]
// ============================================
// PART 8: INITIALIZING FROM ARRAY
// ============================================
const map2 = new Map([
['a', 1],
['b', 2],
['c', 3]
]);
console.log(map2.size);
// [ 3 ]
// ============================================
// PART 9: ITERATING WITH FOR...OF
// ============================================
for (const [key, value] of map2) {
console.log(key, value);
}
// [ a 1 ]
// [ b 2 ]
// [ c 3 ]
// ============================================
// PART 10: ITERATING KEYS
// ============================================
for (const key of map2.keys()) {
console.log(key);
}
// [ a ]
// [ b ]
// [ c ]
// ============================================
// PART 11: ITERATING VALUES
// ============================================
for (const value of map2.values()) {
console.log(value);
}
// [ 1 ]
// [ 2 ]
// [ 3 ]
// ============================================
// PART 12: ENTRIES
// ============================================
console.log([...map2.entries()]);
// [ [ [ 'a', 1 ], [ 'b', 2 ], [ 'c', 3 ] ] ]
// ============================================
// PART 13: FOREACH
// ============================================
map2.forEach((value, key) => {
console.log(`${key} -> ${value}`);
});
// [ a -> 1 ]
// [ b -> 2 ]
// [ c -> 3 ]
// ============================================
// PART 14: COUNTING PATTERN
// ============================================
const words = ['apple', 'banana', 'apple', 'cherry', 'banana', 'apple'];
const counts = new Map();
for (const word of words) {
counts.set(word, (counts.get(word) || 0) + 1);
}
console.log(counts);
// [ Map(3) { 'apple' => 3, 'banana' => 2, 'cherry' => 1 } ]
// ============================================
// PART 15: OBJECTS AS KEYS
// ============================================
const obj1 = { id: 1 };
const obj2 = { id: 2 };
const objMap = new Map();
objMap.set(obj1, 'first');
objMap.set(obj2, 'second');
console.log(objMap.get(obj1));
// [ first ]
console.log(objMap.get({ id: 1 }));
// [ undefined ]
// ============================================
// PART 16: MAP TO OBJECT
// ============================================
const m = new Map([['a', 1], ['b', 2]]);
const o = Object.fromEntries(m);
console.log(o);
// [ { a: 1, b: 2 } ]
// ============================================
// PART 17: OBJECT TO MAP
// ============================================
const obj = { x: 10, y: 20 };
const m2 = new Map(Object.entries(obj));
console.log(m2);
// [ Map(2) { 'x' => 10, 'y' => 20 } ]
// ============================================
// PART 18: GROUPING PATTERN
// ============================================
const people = [
{ name: 'Alice', dept: 'Eng' },
{ name: 'Bob', dept: 'Sales' },
{ name: 'Charlie', dept: 'Eng' }
];
const byDept = new Map();
for (const person of people) {
if (!byDept.has(person.dept)) {
byDept.set(person.dept, []);
}
byDept.get(person.dept).push(person.name);
}
console.log(byDept);
// [ Map(2) { 'Eng' => [ 'Alice', 'Charlie' ], 'Sales' => [ 'Bob' ] } ]
// ============================================
// PART 19: MERGING MAPS
// ============================================
const m3 = new Map([['a', 1], ['b', 2]]);
const m4 = new Map([['b', 99], ['c', 3]]);
const merged = new Map([...m3, ...m4]);
console.log(merged);
// [ Map(3) { 'a' => 1, 'b' => 99, 'c' => 3 } ]
// ============================================
// PART 20: FILTERING
// ============================================
const m5 = new Map([['a', 1], ['b', 2], ['c', 3]]);
const filtered = new Map([...m5].filter(([k, v]) => v > 1));
console.log(filtered);
// [ Map(2) { 'b' => 2, 'c' => 3 } ]
Quick Reference
Creating Maps
| Syntax | Meaning |
|---|---|
new Map() | Empty map |
new Map([['a', 1], ['b', 2]]) | From entries |
new Map(Object.entries(obj)) | From object |
new WeakMap() | Weak map (objects only) |
Map Methods
| Method | Purpose | Returns |
|---|---|---|
set(k, v) | Add or update | The map |
get(k) | Retrieve value | Value or undefined |
has(k) | Check key | Boolean |
delete(k) | Remove entry | Boolean |
clear() | Remove all | undefined |
size | Count | Number |
Map Iteration
| Method | Yields |
|---|---|
for (const [k, v] of map) | [key, value] pairs |
map.keys() | Keys |
map.values() | Values |
map.entries() | [key, value] pairs |
map.forEach((v, k) => ...) | Value first, then key |
Map vs Object
| Feature | Map | Object |
|---|---|---|
| Key types | Any | String/Symbol |
| Size | .size | Object.keys().length |
| Iteration | Direct | Needs Object.* |
| Order | Insertion | Mostly insertion |
| Prototype keys | None | Inherited |
| JSON | No direct | JSON.stringify |
Map vs WeakMap
| Feature | Map | WeakMap |
|---|---|---|
| Key types | Any | Objects only |
| Size | Yes | No |
| Iteration | Yes | No |
| GC | Strong | Weak |
| Use | General | Object metadata |
Converting
| From | To | Code |
|---|---|---|
| Map | Object | Object.fromEntries(map) |
| Object | Map | new Map(Object.entries(obj)) |
| Map | Array | [...map] |
| Array | Map | new Map(arr) |
| Map | JSON | JSON.stringify([...map]) |
Best Practices
✅ Do This:
// Use has before get when undefined is valid
if (map.has(key)) {
const value = map.get(key);
} // ✅
// Use the counting idiom
map.set(k, (map.get(k) || 0) + 1); // ✅
// Destructure entries in for...of
for (const [key, value] of map) { ... } // ✅
// Use Map for object keys
const m = new Map();
m.set(obj, 'data'); // ✅
// Convert with Object.fromEntries / Object.entries
const obj = Object.fromEntries(map); // ✅
// Use WeakMap for metadata on objects
const meta = new WeakMap(); // ✅
// Iterate keys and values directly
for (const k of map.keys()) { ... } // ✅
// Chain set calls
map.set('a', 1).set('b', 2); // ✅
❌ Don’t Do This:
// Don't use get alone if undefined is a valid value
if (map.get(key)) { ... } // ❌ false for 0, '', false
// Don't forget value comes first in forEach
map.forEach((key, value) => ...); // ❌ backwards
// Don't use size as a method
map.size(); // ❌ it's a property
// Don't use Maps for JSON serialization
JSON.stringify(map); // ❌ gives {}
// Don't use weak maps for primitives
new WeakMap().set(1, 'x'); // ❌ TypeError
// Don't assume two equal objects are the same key
m.set({id: 1}, 'a');
m.get({id: 1}); // ❌ undefined
// Don't iterate and mutate carelessly
for (const [k, v] of map) {
map.delete(k); // ⚠️ may skip entries
}
// Don't mix bracket notation
map['key'] = 'value'; // ❌ this sets a property, not an entry
Common Pitfalls
| Pitfall | Problem | Solution |
|---|---|---|
map.size() | TypeError | map.size (property) |
map.get(k) returns undefined | Can’t tell missing from undefined value | Use map.has(k) first |
forEach arg order | Value first, then key | (value, key) => ... |
JSON.stringify(map) | {} | JSON.stringify([...map]) |
| Object keys not matching | Each object literal is a new key | Store the object reference |
| Mutating while iterating | Skips or errors | Collect keys first, then delete |
WeakMap with primitives | TypeError | Only objects allowed |
| Bracket notation on Map | Sets a property, not an entry | Use map.set() |
Real-World Examples
1. Basic Map Operations
const map = new Map();
map.set('name', 'Alice');
map.set('age', 30);
map.set(1, 'one');
console.log(map.get('name'));
// [ Alice ]
console.log(map.has('age'));
// [ true ]
console.log(map.size);
// [ 3 ]
map.delete('age');
console.log(map.size);
// [ 2 ]
map.clear();
console.log(map.size);
// [ 0 ]
2. Initialize from Array
const map2 = new Map([
['a', 1],
['b', 2],
['c', 3]
]);
for (const [key, value] of map2) {
console.log(key, value);
}
// [ a 1 ]
// [ b 2 ]
// [ c 3 ]
3. Word Frequency
const text = 'the quick brown fox jumps over the lazy dog the fox';
const counts = new Map();
for (const word of text.split(' ')) {
counts.set(word, (counts.get(word) || 0) + 1);
}
console.log(counts.get('the'));
// [ 3 ]
4. Group by Property
const people = [
{ name: 'Alice', dept: 'Eng' },
{ name: 'Bob', dept: 'Sales' },
{ name: 'Charlie', dept: 'Eng' }
];
const byDept = new Map();
for (const p of people) {
if (!byDept.has(p.dept)) byDept.set(p.dept, []);
byDept.get(p.dept).push(p.name);
}
console.log(byDept.get('Eng'));
// [ [ 'Alice', 'Charlie' ] ]
5. Object Keys
const users = [{ id: 1 }, { id: 2 }];
const roles = new Map();
roles.set(users[0], 'admin');
roles.set(users[1], 'viewer');
console.log(roles.get(users[0]));
// [ admin ]
6. Cache / Memoize
const cache = new Map();
function fib(n) {
if (n < 2) return n;
if (cache.has(n)) return cache.get(n);
const result = fib(n - 1) + fib(n - 2);
cache.set(n, result);
return result;
}
console.log(fib(40));
// [ 102334155 ]
7. Map to Object
const map = new Map([['a', 1], ['b', 2]]);
const obj = Object.fromEntries(map);
console.log(obj);
// [ { a: 1, b: 2 } ]
8. Object to Map
const obj = { x: 10, y: 20 };
const map = new Map(Object.entries(obj));
console.log(map.get('x'));
// [ 10 ]
9. Merge Two Maps
const m1 = new Map([['a', 1], ['b', 2]]);
const m2 = new Map([['b', 99], ['c', 3]]);
const merged = new Map([...m1, ...m2]);
console.log(merged.get('b'));
// [ 99 ]
10. Filter a Map
const map = new Map([['a', 1], ['b', 2], ['c', 3]]);
const filtered = new Map([...map].filter(([k, v]) => v > 1));
console.log([...filtered.keys()]);
// [ [ 'b', 'c' ] ]
11. Map from Query String
const qs = 'name=Alice&age=30&city=Paris';
const params = new Map(
qs.split('&').map(pair => pair.split('='))
);
console.log(params.get('name'));
// [ Alice ]
12. Invert a Map
const original = new Map([['a', 1], ['b', 2]]);
const inverted = new Map([...original].map(([k, v]) => [v, k]));
console.log(inverted.get(1));
// [ a ]
13. Track Unique Values
const values = [1, 2, 2, 3, 3, 3];
const seen = new Map();
for (const v of values) {
seen.set(v, true);
}
console.log(seen.size);
// [ 3 ]
14. Sort a Map by Value
const map = new Map([['a', 3], ['b', 1], ['c', 2]]);
const sorted = new Map(
[...map].sort((a, b) => a[1] - b[1])
);
console.log([...sorted]);
// [ [ [ 'b', 1 ], [ 'c', 2 ], [ 'a', 3 ] ] ]
15. Map of Sets
const graph = new Map();
graph.set('A', new Set(['B', 'C']));
graph.set('B', new Set(['A']));
graph.set('C', new Set(['A']));
console.log(graph.get('A').has('B'));
// [ true ]
16. Preserve Insertion Order
const map = new Map();
map.set('z', 1);
map.set('a', 2);
map.set('m', 3);
console.log([...map.keys()]);
// [ [ 'z', 'a', 'm' ] ]
17. WeakMap for Private Data
const priv = new WeakMap();
class Counter {
constructor() {
priv.set(this, { count: 0 });
}
increment() {
priv.get(this).count++;
return priv.get(this).count;
}
}
const c = new Counter();
console.log(c.increment());
// [ 1 ]
18. Map of Functions
const handlers = new Map();
handlers.set('add', (a, b) => a + b);
handlers.set('sub', (a, b) => a - b);
console.log(handlers.get('add')(5, 3));
// [ 8 ]
19. Deduplicate Array
const arr = [1, 2, 2, 3, 1, 4, 3];
const unique = [...new Map(arr.map(v => [v, v])).values()];
console.log(unique);
// [ [ 1, 2, 3, 4 ] ]
20. Full Script
const map = new Map();
map.set('name', 'Alice');
map.set('age', 30);
map.set(1, 'one');
console.log(map.get('name'));
console.log(map.has('age'));
console.log(map.size);
map.delete('age');
console.log(map.size);
map.clear();
console.log(map.size);
const map2 = new Map([
['a', 1],
['b', 2],
['c', 3]
]);
for (const [key, value] of map2) {
console.log(key, value);
}
Visual: Map vs Object
┌──────────────────────────────────────────────┐
│ Map (any key type) │
│ │
│ ┌──────────────┬──────────────┐ │
│ │ key │ value │ │
│ ├──────────────┼──────────────┤ │
│ │ 'name' │ 'Alice' │ │
│ │ 42 │ 'answer' │ │
│ │ {id: 1} │ 'user' │ │
│ │ [1, 2, 3] │ 'array key' │ │
│ └──────────────┴──────────────┘ │
│ │
│ map.size → 4 │
│ Directly iterable │
│ │
└──────────────────────────────────────────────┘
┌──────────────────────────────────────────────┐
│ Object (string keys only) │
│ │
│ { │
│ name: 'Alice', │
│ 42: 'answer', ← becomes '42' │
│ '[object Object]': 'user' │
│ } │
│ │
│ Object.keys(obj).length → 3 │
│ Not directly iterable │
│ │
└──────────────────────────────────────────────┘
Visual: Map Iteration Order
┌──────────────────────────────────────────────┐
│ const m = new Map(); │
│ m.set('z', 1); │
│ m.set('a', 2); │
│ m.set('m', 3); │
│ │
│ Iteration order: │
│ ┌───────────────────────────────┐ │
│ │ 'z' => 1 ← inserted first │ │
│ │ 'a' => 2 ← inserted second │ │
│ │ 'm' => 3 ← inserted third │ │
│ └───────────────────────────────┘ │
│ │
│ Order is guaranteed — insertion order │
│ │
└──────────────────────────────────────────────┘
Summary
| Concept | Syntax | Example |
|---|---|---|
| Create | new Map() | const m = new Map() |
| From entries | new Map([...]) | new Map([['a', 1]]) |
| Set | map.set(k, v) | map.set('name', 'Alice') |
| Get | map.get(k) | map.get('name') |
| Has | map.has(k) | map.has('name') |
| Delete | map.delete(k) | map.delete('name') |
| Clear | map.clear() | map.clear() |
| Size | map.size | console.log(map.size) |
| Keys | map.keys() | [...map.keys()] |
| Values | map.values() | [...map.values()] |
| Entries | map.entries() | [...map.entries()] |
| ForEach | map.forEach(...) | (v, k) => ... |
| For…of | for (const [k, v] of map) | |
| Map to object | Object.fromEntries(map) | |
| Object to map | new Map(Object.entries(obj)) | |
| Map to array | [...map] | |
| WeakMap | new WeakMap() | Objects only |
Key takeaways:
Mapholds key-value pairs where keys can be any type — objects, functions, numbers, arraysset,get,has,delete,clearare the core methods.sizeis a property, not a method- Iteration is guaranteed to follow insertion order
- Use
for...ofwith destructuring to iterate entries:for (const [k, v] of map) - Use
map.has(k)beforemap.get(k)whenundefinedcould be a valid value map.forEach((value, key) => ...)takes value first, key secondJSON.stringify(map)returns{}— convert with[...map]first- Two equal objects are different keys in a Map — use the object reference
WeakMapis for attaching data to objects without preventing garbage collection- Convert between Map, Object, and Array with
Object.fromEntries,Object.entries, and spread - Common patterns: counting, grouping, caching, object keying, deduplication
Remember: Reach for Map when your keys aren’t plain strings, when you need to know the size, when you iterate, or when you add and remove entries frequently. It’s cleaner than a plain object for dynamic key-value data. Use set, get, has, delete, and size as your core API. Iterate with for...of and destructuring. Watch out for the forEach argument order and the fact that size is not a function. Master Map, and your dictionary-style code becomes cleaner, safer, and faster.
Stop using slow, ad-bloated tool sites! 🤮
🔎 Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)
⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free
🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!