Topic 25 of 26 · UI Designer

Topic 10 : JavaScript Map Object

Lesson TL;DRTopic 10: JavaScript Map Object 📖 5 min read · 🎯 Advanced · 🧭 Prerequisites: tagslist, javascriptobject Why this matters Up until now, you've probably stored data in plain JavaScript objects — some...
5 min read·advanced·javascript · map-object · key-value · iteration

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, and size
  • How to iterate over a Map using for...of and forEach
  • 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.

  1. Create a Map called sessions.
  2. Add three entries using randomly generated string keys (e.g. 'sess_a1b2') mapped to objects with { userId, role, loginTime }.
  3. Log the size of the map.
  4. Iterate with forEach and print each session in the format: [sess_a1b2] userId=42 role=admin.
  5. Delete one session by key, then confirm with has.
  6. Call clear() and log sessions.size — it should print 0.

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 Map stores key-value pairs where keys can be any type, not just strings or Symbols.
  • Maps preserve insertion order and expose a direct size property — two things plain objects don't guarantee.
  • The core API is set, get, has, delete, clear, and size.
  • 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

Like this topic? It’s one of 26 in UI Designer.

Block your seat for ₹2,500 and join the next cohort.