Map is a dedicated key-value collection that fixes several long-standing limitations of using plain objects as maps: any value type as a key, guaranteed iteration order, and a reliable size property.
1The Map Collection | JavaScript Tutorial - In-Depth Guide Part 1
A Map stores key-value pairs where keys can be of ANY type β objects, functions, even other Maps β not just strings like plain object keys.
const map = new Map();
const userObj = { id: 1 };
map.set(userObj, 'active');
map.get(userObj); // 'active'Any Type as a Key
2The Map Collection | JavaScript Tutorial - In-Depth Guide Part 2
Map has a real 'size' property, unlike plain objects which require Object.keys(obj).length to count entries.
const map = new Map([['a', 1], ['b', 2]]);
map.size; // 2Native size Property
3The Map Collection | JavaScript Tutorial - In-Depth Guide Part 3
A Map guarantees iteration in insertion order, and is directly iterable with for...of β no need for Object.entries() first.
for (const [key, value] of map) {
console.log(key, value);
}Guaranteed Order, Direct Iteration
4The Map Collection | JavaScript Tutorial - In-Depth Guide Part 4
Map performs better than a plain object for frequent additions and removals of keys, since engines can optimize it specifically for that access pattern.
const cache = new Map();
cache.set(requestId, response);
cache.delete(oldRequestId); // efficientBetter for Dynamic Keys
5The Map Collection | JavaScript Tutorial - In-Depth Guide Part 5
Use a plain object for a fixed, known set of named fields (like a record), and a Map for a genuinely dynamic collection of key-value pairs.
// Record: use an object
const user = { name: 'Ana', age: 28 };
// Dictionary: use a Map
const sessionsByUserId = new Map();Map vs Object: When to Use Each
6Step-by-Step Breakdown
A Map stores key-value pairs where keys can be of ANY type β objects, functions, even other Maps β not just strings like plain object keys.
Checkpoint: Can a Map use an object (not just a string) as a key while preserving its identity?
- βYes, Map supports any value type as a key
- βNo, all keys are coerced to strings, just like plain objects
Map has a real 'size' property, unlike plain objects which require Object.keys(obj).length to count entries.
A Map guarantees iteration in insertion order, and is directly iterable with for...of β no need for Object.entries() first.
Checkpoint: Does a Map guarantee that iteration happens in the order entries were inserted?
- βYes, always in insertion order
- βNo, the order is unspecified
Map performs better than a plain object for frequent additions and removals of keys, since engines can optimize it specifically for that access pattern.
Use a plain object for a fixed, known set of named fields (like a record), and a Map for a genuinely dynamic collection of key-value pairs.
Next, we'll explore 'The Set Collection'.
Level Up π
Advanced cheat sheets, SEO tricks, and interview prep for this topic.
Browser Support
Fully supported.
Fully supported.
Fully supported.
Fully supported.
Accessibility (A11y)
1Use a Map to Associate Accessibility Metadata with Live DOM Nodes
Tracking per-element focus history or ARIA state changes in a Map keyed by the actual DOM element avoids polluting the elements themselves with custom data attributes that assistive technology or other scripts might misinterpret.
SEO Implications
- 1
No Direct SEO Effect
Map is an in-memory data structure choice; SEO relevance is limited to general application correctness and performance.
Best Practices
Use Map for Dynamic, Frequently-Changing Key-Value Collections
Its native size tracking, guaranteed order, and support for non-string keys make it a better fit than a plain object for genuine dictionary use cases.
Use Plain Objects for Fixed-Shape Records
When the set of keys is known and stable (like a typed data record), a plain object remains more idiomatic, JSON-serializable by default, and destructuring-friendly.
Frequent Bugs
Using a plain object as a cache keyed by object references, only to discover every object key silently coerces to the same string ('[object Object]'), causing entries to overwrite each other.
Switch to a Map, which preserves object keys by reference instead of coercing them to strings.
Calling `Object.keys(obj).length` out of habit to get an entry count on a Map, which doesn't work since Map isn't a plain object.
Use the Map's native `.size` property instead.
Real-World Examples
Caching Computed Results Keyed by DOM Elements
A UI library needed to associate computed layout data with specific DOM element references, without adding custom properties directly onto the elements themselves.
const layoutCache = new Map();
layoutCache.set(domElement, { width: 200, height: 100 });
layoutCache.get(domElement);