Both store key-value pairs. They are not the same, and each is better at some jobs.
| Object | Map | |
|---|---|---|
| Key types | strings and symbols (everything else becomes a string) | any value |
| Size | Object.keys(obj).length | map.size |
| Iteration | needs Object.entries() | directly iterable |
| Order | mostly insertion order (with integer-like keys first) | always insertion order |
| Default keys | inherits from the prototype (toString…) | none |
| JSON | works directly | needs converting |
| Syntax | literal { }, dot access | methods get, set |
| Frequent adding/removing | okay | designed for it |
Use an object when
- You have a fixed set of known fields: a user, a product, settings.
- The data is structured like a record, accessed with dot notation:
user.name. - You need JSON: sending to servers, saving to storage.
- You want destructuring and spread.
const user = { name: "Maya", age: 28 };
Use a Map when
- Keys are unknown or dynamic (words in a text, ids from data, user input).
- Keys are not strings: DOM elements, objects, numbers.
- You need to add and remove entries often, and ask for the size.
- You care about insertion order.
const clicksByButton = new Map();
document.querySelectorAll("button").forEach(button => {
clicksByButton.set(button, 0); // the DOM element itself is the key
});
console.log(clicksByButton.size); // → 0 (no buttons on this empty page)
The prototype problem with objects
Objects inherit properties. A user-supplied key like "constructor" or "__proto__" can cause trouble.
const counts = {};
const word = "constructor";
counts[word] = (counts[word] ?? 0) + 1;
console.log(counts[word]); // → function Object() { [native code] }1 (not what you wanted!)
const safe = new Map();
safe.set(word, (safe.get(word) ?? 0) + 1);
console.log(safe.get(word)); // → 1
For dictionaries built from arbitrary text, use a Map (or Object.create(null)).
Number keys
const obj = { 1: "one" };
const map = new Map([[1, "one"]]);
console.log(obj["1"], obj[1]); // → one one (the key became a string)
console.log(map.get(1), map.get("1")); // → one undefined
Converting
const map = new Map(Object.entries(obj));
const object = Object.fromEntries(map);
A quick guide
> Record with known fields? Object. > Dictionary with dynamic or non-string keys? Map.
Most day-to-day data (API results, settings, user profiles) is objects. Reach for Map for lookups and counting.