Map vs Object in JavaScript: Complete Guide

Compare Map and Object in JavaScript across key types, performance, iteration, safety, and serialization. Learn which to choose for your data storage needs.

6 min read

Both Map and plain objects store key-value pairs. For years, objects were the only option, so they became the default. But Map was added in ES6 to solve specific problems that objects have. The question is not which one is better overall, but which one fits your current task.

The Core Differences

MapObject
Key typesAny value: objects, functions, primitivesStrings and Symbols only
Default keysNone (clean slate)Inherited from prototype (toString, etc.)
Insertion orderGuaranteed, simpleComplex, varies by key type
Sizemap.size (property, O(1))Object.keys(obj).length (O(n))
IterationDirectly iterable, for...ofRequires Object.keys/values/entries
PerformanceOptimized for frequent add/deleteOptimized for static property access
JSONNot serializable nativelyNative JSON.stringify/parse
Prototype safetyNo prototype chain interferenceRisk of key collision with inherited properties

Key Types: The Biggest Difference

Map accepts any value as a key, and it keeps that value exactly as given, whether it is an object, a function, or a number:

javascriptjavascript
const map = new Map();
const keyObj = { id: 1 };
const keyFunc = () => "hello";
 
map.set(keyObj, "object key works");
map.set(keyFunc, "function key works");
map.set(42, "number key works");
 
console.log(map.get(keyObj)); // "object key works"

An object cannot do the same thing, because every key you assign to it is coerced to a string via .toString() first. Two different objects both become the literal string "[object Object]" and collide:

javascriptjavascript
const obj = {};
const keyObj = { id: 1 };
const anotherKeyObj = { id: 2 };
 
obj[keyObj] = "first";
obj[anotherKeyObj] = "second";
 
console.log(obj["[object Object]"]); // "second" (overwrote the first one)

The Prototype Pollution Problem

Every plain object inherits properties from Object.prototype. If a key happens to match an inherited property name, you get unexpected behavior:

javascriptjavascript
const obj = {};
obj["toString"] = "hello";
obj["constructor"] = "world";
 
console.log(obj.toString); // [Function: toString] (inherited, not "hello")
console.log(typeof obj.toString); // "function"

Map has no such issue, because it does not inherit a set of default keys the way a plain object inherits from Object.prototype. It starts completely empty:

javascriptjavascript
const map = new Map();
map.set("toString", "hello");
map.set("constructor", "world");
 
console.log(map.get("toString")); // "hello"
console.log(map.get("constructor")); // "world"

This matters when keys come from user input, API responses, or file parsing. For more on Map basics, see the article on /javascript/javascript-map-object-complete-guide.

Iteration and Order

Map is designed for iteration. You can loop directly with for...of, and order matches insertion:

javascriptjavascript
const map = new Map();
map.set("z", 1);
map.set("a", 2);
map.set("m", 3);
 
for (const [key, value] of map) {
  console.log(key); // z, a, m (insertion order)
}

Objects require extra steps to iterate, and the order of the resulting keys is less predictable than a Map's, especially once numeric-looking keys get involved:

javascriptjavascript
const obj = { z: 1, a: 2, 3: "numeric" };
 
console.log(Object.keys(obj)); // ["3", "z", "a"] (numeric keys sort first!)

Performance: When It Matters

Map is optimized for scenarios where entries are frequently added and removed. Object is optimized for static shapes where property names are known at parse time:

  • Frequent mutations: Map is faster. Adding and deleting entries is O(1) on average.
  • Static property access: Object is comparable, especially when the engine can optimize for known property shapes (hidden classes).
  • Finding the size: map.size is instant. Object.keys(obj).length creates an array first.

For most everyday code, the performance difference is negligible. Choose based on the API and safety needs, not micro-benchmarks.

JSON Serialization

This is where Object has a clear advantage. JSON.stringify() works on objects but ignores Map:

javascriptjavascript
const obj = { name: "Alex", age: 28 };
console.log(JSON.stringify(obj)); // {"name":"Alex","age":28}
 
const map = new Map([["name", "Alex"], ["age", 28]]);
console.log(JSON.stringify(map)); // {} (empty!)

To serialize a Map, convert it to an array of entries first, then reverse the process with the Map constructor when you read it back:

javascriptjavascript
const serialized = JSON.stringify([...map]);
console.log(serialized); // [["name","Alex"],["age",28]]
 
// Deserialize
const restored = new Map(JSON.parse(serialized));
console.log(restored.get("name")); // "Alex"

If your data needs to survive JSON.stringify and JSON.parse round trips, stick with objects or handle the conversion manually. For techniques to iterate and transform objects, see the article on /javascript/javascript-object-keys-values-and-entries-guide.

When to Use Each

The differences covered so far come down to a few branching questions. Walk through them in order and you will land on the right collection for your situation:

Map vs Object decision guide

The decision tree shows the primary trade-offs. In practice, many codebases use Object for configuration and data transfer, and Map for dynamic collections, caches, and situations where keys are not known ahead of time.

Rune AI

Rune AI

Key Insights

  • Map accepts any type as keys; Object keys are strings or symbols.
  • Map guarantees insertion order; Object order is complex and less reliable.
  • Map is safe from prototype pollution; Object can collide with inherited properties.
  • Map is iterable directly; Object requires Object.keys/values/entries.
  • Object supports JSON serialization natively; Map requires manual conversion.
RunePowered by Rune AI

Frequently Asked Questions

Is Map faster than Object?

Map performs better for frequent additions and removals of key-value pairs. For static data accessed by known string keys, Object is comparable. The real advantage of Map is key flexibility and safety, not raw speed.

Can Map be serialized to JSON?

Not natively. JSON.stringify() ignores Map entries. To serialize a Map, convert it to an array of entries first: JSON.stringify([...map]). Use new Map(JSON.parse(json)) to deserialize.

Should I always use Map instead of Object?

No. Object is still the right choice for fixed-shape data with string keys, JSON serialization, and APIs that expect plain objects. Use Map when you need non-string keys, guaranteed insertion order, frequent mutations, or protection from prototype pollution.

Conclusion

Map and Object overlap in purpose but diverge in key flexibility, safety, and performance characteristics. Choose Map when keys are dynamic, non-string, or user-provided. Choose Object for static shapes, JSON interchange, and classical key-value patterns. Knowing both lets you pick the right tool for each situation.| Scenario | Recommendation | |---|---| | Fixed set of string keys (config, options) | Object | | Data going to or from an API as JSON | Object | | Keys are anything other than strings | Map | | Keys are dynamic or from user input | Map | | Need to frequently add and remove entries | Map | | Need reliable insertion order | Map | | Building a cache or lookup table | Map | | Simple static record with known shape | Object |