Map.prototype.keys, values, entries and forEach
All four traverse entries in insertion order, guaranteed, whatever the key types. That guarantee is what an object cannot give you: integer-like keys always jump to the front there.
Demo
The first case is the whole argument for Map. The keys were inserted as 'b', 2, 'a' and they come back in exactly that order. Build the same data as an object and Object.keys gives ['2', 'b', 'a'] — the integer-like key is moved to the front and converted to a string. The third case makes it starker: keys 3, 1, 2 stay in that order here, where an object would sort them to 1, 2, 3. If order carries meaning, an object is the wrong container.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| callback | Function | no (none) | For forEach only. Called as callback(value, key, map) — value first, which is the opposite order from Object.entries pairs. |
Return value
Iterator — The first three return iterators, not arrays — spread them or loop them. forEach returns undefined and calls back with (value, key, map) — value FIRST.
Common patterns
for (const [key, value] of map) { }
const total = [...map.values()].reduce((a, b) => a + b, 0);
map.forEach((value, key) => console.log(key, value));
Examples
Pitfalls
new Map([["a", 1]]).forEach((k, v) => `${k}=${v}`)
new Map([["a", 1]]).forEach((v, k) => `${k}=${v}`)
new Map([["a", 1]]).values().map(x => x)
[...new Map([["a", 1]]).values()].map(x => x)
({...new Map([["a", 1]])})
Object.fromEntries(new Map([["a", 1]]))
for (const [k] of m) m.set(k + "x", 1);
for (const [k] of [...m]) m.set(k + "x", 1);
When to use
- Iterating a collection where insertion order matters
- Keys that are numbers or objects, where an object would reorder or coerce
- Feeding keys or values into array methods, via spread
- Converting to pairs for serialisation
- You want array methods directly → spread first, or keep an array
- Serialising → Object.fromEntries or spread to pairs
- Order does not matter and keys are strings → an object is simpler
- You need random access by index → an array
Notes
FAQ
No — a Map is iterable and its default iterator IS entries, so for...of over the Map itself yields [key, value] pairs. Writing entries() explicitly is harmless and occasionally clearer.
for (const [k, v] of map) { } for (const [k, v] of map.entries()) { } // identical