Topic 10: JavaScript Map Object
📖 5 min read · 🎯 Advanced · 🧭 Prerequisites: tags-list, javascript-object
Why this matters
Up until now, you've probably stored data in plain JavaScript objects — something like { name: "Ravi", role: "trainer" }. That works fine for small things, but objects have quiet limitations: keys can only be strings, the order you add entries isn't always preserved, and looping over them feels clunky. The Map object fixes all of that. It's JavaScript's purpose-built key-value store — same idea as an object, but cleaner, more predictable, and built for real data work. Once you see how it behaves, you'll reach for it often.
What You'll Learn
- What a JavaScript Map is and how it differs from a plain object
- How to create a Map and use
set,get,has,delete,clear, andsize - How to iterate over a Map using
for...ofandforEach - How to use a Map to store and manage structured user data in a practical example
The Analogy
Think of a Map like a coat-check at a fancy Vizag gala. When you arrive, the attendant gives you a numbered ticket — that's your key — and hangs your coat on the exact matching hook. You can hand in any kind of ticket (a number, an object, even another function — not just a string label), the attendant always remembers the order coats arrived, and retrieving your coat is instantaneous because they go straight to the right hook. A plain JavaScript object is more like tossing your coat on a pile labeled with sticky notes: string-only labels, no guaranteed order, and hunting through the pile yourself.
Chapter 1: What is a Map?
A Map in JavaScript is a collection of key-value pairs where both keys and values can be of any type — strings, numbers, objects, functions, anything. This is the first major difference from plain objects, which only allow string (or Symbol) keys.
The second major difference is insertion-order preservation. A Map always remembers the order in which entries were added, and iteration respects that order. Plain objects do not provide this guarantee.
Key characteristics at a glance:
- Keys can be any value, including objects and primitives
- Insertion order is maintained
- Built-in size property (no need for
Object.keys(obj).length) - Cleaner iteration support via
for...of,.keys(),.values(),.entries(), and.forEach() - No prototype-chain collisions — a Map has no inherited keys
Chapter 2: Creating and Using a Map
Creating a Map
Use the Map constructor with no arguments to start empty:
let map = new Map();
You can also initialize a Map from an array of [key, value] pairs:
let map = new Map([
['name', 'Alice'],
['age', 25],
['city', 'Vizag']
]);
Adding Elements — set
The set method adds a key-value pair. If the key already exists, its value is updated:
map.set('name', 'Alice');
map.set('age', 25);
map.set('city', 'Vizag');
Accessing Elements — get
The get method retrieves the value for a given key. Returns undefined if the key does not exist:
console.log(map.get('name')); // Output: Alice
console.log(map.get('age')); // Output: 25
Checking for Keys — has
The has method returns true if the key exists in the Map, false otherwise:
console.log(map.has('city')); // Output: true
console.log(map.has('country')); // Output: false
Removing Elements — delete
The delete method removes the entry for the given key and returns true if the key existed:
map.delete('age');
console.log(map.has('age')); // Output: false
Clearing All Elements — clear
The clear method removes every entry from the Map at once:
map.clear();
console.log(map.size); // Output: 0
Checking the Size — size
Unlike objects (which require Object.keys(obj).length), Maps expose a direct size property:
let map = new Map([['a', 1], ['b', 2]]);
console.log(map.size); // Output: 2
Chapter 3: Iterating Over a Map
One of the Map's strongest selling points is first-class, ordered iteration. kiran walked the class through three iteration patterns.
Using the for...of Loop
A bare for...of loop over a Map yields [key, value] pairs. Destructure them directly:
let map = new Map([
['name', 'Alice'],
['age', 25],
['city', 'Vizag']
]);
// Iterating over entries (key + value together)
for (let [key, value] of map) {
console.log(key + ": " + value);
}
// Output:
// name: Alice
// age: 25
// city: Vizag
// Iterating over keys only
for (let key of map.keys()) {
console.log(key);
}
// Output: name, age, city
// Iterating over values only
for (let value of map.values()) {
console.log(value);
}
// Output: Alice, 25, Vizag
Using the forEach Method
forEach passes (value, key, map) to the callback — note the value-first order (matching the Array forEach convention):
map.forEach((value, key) => {
console.log(key + ": " + value);
});
// Output:
// name: Alice
// age: 25
// city: Vizag
flowchart LR
A[Map] --> B{Iteration method}
B --> C["for...of map\n→ [key, value] pairs"]
B --> D["map.keys()\n→ keys only"]
B --> E["map.values()\n→ values only"]
B --> F["map.forEach(cb)\n→ (value, key) callback"]
Chapter 4: Practical Example — Storing User Information
The class put everything together by building a user registry backed by a Map. Note how numeric IDs work as keys directly — no string conversion needed:
// Creating a new Map
let users = new Map();
// Adding users to the Map — numeric keys, object values
users.set(1, { name: 'Alice', age: 25, city: 'Vizag' });
users.set(2, { name: 'Bob', age: 30, city: 'CoderTown' });
users.set(3, { name: 'Charlie', age: 35, city: 'DevCity' });
// Retrieving user information
console.log(users.get(1)); // Output: { name: 'Alice', age: 25, city: 'Vizag' }
console.log(users.get(2).name); // Output: Bob
// Iterating over all users
users.forEach((user, id) => {
console.log(`ID: ${id}, Name: ${user.name}, Age: ${user.age}, City: ${user.city}`);
});
// Output:
// ID: 1, Name: Alice, Age: 25, City: Vizag
// ID: 2, Name: Bob, Age: 30, City: CoderTown
// ID: 3, Name: Charlie, Age: 35, City: DevCity
// Checking if a user exists
console.log(users.has(3)); // Output: true
// Deleting a user
users.delete(2);
console.log(users.has(2)); // Output: false
// Clearing all users
users.clear();
console.log(users.size); // Output: 0
This pattern is ideal any time you need numeric or object keys, guaranteed iteration order, or frequent add/delete operations on a keyed collection.
🧪 Try It Yourself
Task: Build a session store for a small web app.
- Create a Map called
sessions. - Add three entries using randomly generated string keys (e.g.
'sess_a1b2') mapped to objects with{ userId, role, loginTime }. - Log the
sizeof the map. - Iterate with
forEachand print each session in the format:[sess_a1b2] userId=42 role=admin. - Delete one session by key, then confirm with
has. - Call
clear()and logsessions.size— it should print0.
Starter snippet:
let sessions = new Map();
sessions.set('sess_a1b2', { userId: 42, role: 'admin', loginTime: Date.now() });
sessions.set('sess_c3d4', { userId: 17, role: 'editor', loginTime: Date.now() });
sessions.set('sess_e5f6', { userId: 99, role: 'viewer', loginTime: Date.now() });
console.log('Active sessions:', sessions.size); // Should print 3
sessions.forEach((session, key) => {
console.log(`[${key}] userId=${session.userId} role=${session.role}`);
});
sessions.delete('sess_c3d4');
console.log('sess_c3d4 still active?', sessions.has('sess_c3d4')); // false
sessions.clear();
console.log('Sessions after clear:', sessions.size); // 0
Success criterion: You see Active sessions: 3, all three session lines, sess_c3d4 still active? false, and Sessions after clear: 0 in the console.
🔍 Checkpoint Quiz
Q1. What is the key difference between a JavaScript Map and a plain object when it comes to key types?
A) Maps only allow string keys; objects allow any type
B) Maps allow any type as a key; objects only allow strings and Symbols
C) Both allow any key type
D) Maps only allow numeric keys
Q2. Given this code, what does the final console.log print?
let m = new Map();
m.set('x', 10);
m.set('y', 20);
m.delete('x');
console.log(m.size);
A) 0
B) 1
C) 2
D) undefined
Q3. What is the output of the following snippet?
let m = new Map([['a', 1], ['b', 2], ['c', 3]]);
let result = [];
m.forEach((value, key) => result.push(key));
console.log(result.join('-'));
A) 1-2-3
B) a-b-c
C) a:1-b:2-c:3
D) undefined
Q4. You need to cache API responses keyed by a request-options object (not a string URL). Which data structure should you use, and why?
A1. B — Maps accept any value (including objects, functions, and numbers) as keys. Plain objects coerce keys to strings (or Symbols), which collapses distinct object references to "[object Object]".
A2. B — After set('x', 10) and set('y', 20) the map has 2 entries; delete('x') removes one, leaving size === 1.
A3. B — forEach yields (value, key), so key is pushed into result. The keys in insertion order are 'a', 'b', 'c', joined with - → a-b-c.
A4. Use a Map. A plain object would stringify the object key to "[object Object]", collapsing all entries into one slot. A Map preserves object-reference identity as a key, so each unique options object correctly maps to its own cached response.
🪞 Recap
- A
Mapstores key-value pairs where keys can be any type, not just strings or Symbols. - Maps preserve insertion order and expose a direct
sizeproperty — two things plain objects don't guarantee. - The core API is
set,get,has,delete,clear, andsize. - Maps support clean, ordered iteration via
for...of(with.keys(),.values()) and.forEach((value, key) => …). - Use a Map instead of a plain object whenever you need non-string keys, guaranteed ordering, or frequent adds and deletes on a keyed collection.
📚 Further Reading
- MDN: Map — JavaScript — the authoritative reference for every Map method and property
- JavaScript.info: Map and Set — clear walkthrough with interactive examples comparing Map to plain objects
- Exploring ES6 by Dr. Axel Rauschmayer — deep-dive chapter on Maps, Sets, and WeakMaps for readers who want the full specification story
- ⬅️ Previous: JavaScript Object
- ➡️ Next: JavaScript Misc