Back

What's the Difference Between Map, Set, and Object in JavaScript?

What's the Difference Between Map, Set, and Object in JavaScript?

You’re refactoring a component and need to store key-value pairs. You reach for an object out of habit, then pause. Should this be a Map? Would a Set work better here? This decision matters more than it seems—each structure has distinct performance characteristics and semantic meaning that affect your code’s clarity and efficiency.

This JavaScript data structures comparison breaks down the practical differences between Map, Set, and Object so you can make the right choice in production code.

Key Takeaways

  • Objects coerce keys to strings, while Maps preserve key types exactly—this distinction prevents subtle collision bugs.
  • Maps outperform Objects for frequent additions and deletions, whereas Objects excel at read-heavy workloads with stable shapes.
  • Sets provide O(1) membership checks and now ship with native union, intersection, and difference methods in modern JavaScript.
  • Default to Objects for structured data, reach for Maps when keys are dynamic or non-string, and use Sets when uniqueness is your primary concern.

Core Purpose: When to Use Map vs Set vs Object

The difference between Map and Object in JavaScript comes down to intent and key handling:

  • Object: Structured data with known string/symbol keys. Think configuration, component props, API responses.
  • Map: Dynamic key-value collections where keys can be any type. Think caches, lookup tables with object keys, frequent additions and deletions.
  • Set: Unique value collections without keys. Think deduplication, tracking seen items, membership checks.

Key Handling: The Fundamental Difference Between Map and Object

Objects coerce keys to strings. Maps preserve key types exactly.

const obj = {}
obj[1] = 'number'
obj['1'] = 'string'
console.log(Object.keys(obj)) // ['1'] — collision

const map = new Map()
map.set(1, 'number')
map.set('1', 'string')
console.log(map.size) // 2 — distinct keys

Maps also accept objects as keys—something objects fundamentally cannot do without serialization workarounds.

const userCache = new Map()
const user = { id: 42 }
userCache.set(user, { lastSeen: Date.now() })

See the MDN documentation for Map for full key semantics.

Iteration and Ordering Semantics

All three structures have defined iteration order, but the semantics differ:

Map and Set: Pure insertion order. Always.

Object: Insertion order for string keys, but integer-indexed keys (e.g., '1', '42') sort numerically first. This catches developers off guard:

const obj = { b: 1, 2: 2, a: 3, 1: 4 }
console.log(Object.keys(obj)) // ['1', '2', 'b', 'a']

Maps and Sets are directly iterable with for...of. Objects require Object.keys(), Object.values(), or Object.entries().

Performance Characteristics at Scale

For the JavaScript Map vs Set vs Object performance question, context matters:

Objects excel at read-heavy workloads with string keys. Modern engines like V8 optimize property access through hidden classes, making reads very fast—when the object shape remains stable.

Maps win for frequent additions and deletions. Object property deletion (via delete) can trigger deoptimization by invalidating hidden classes. The ECMAScript specification guarantees sublinear average access time for Maps, without mandating a specific internal implementation.

Sets provide O(1) membership checks via has(), outperforming array includes() for any non-trivial collection size.

Native Set Operations

Set now includes built-in methods for common operations (see MDN’s documentation for Set):

const a = new Set([1, 2, 3])
const b = new Set([2, 3, 4])

a.union(b)               // Set {1, 2, 3, 4}
a.intersection(b)        // Set {2, 3}
a.difference(b)          // Set {1}
a.symmetricDifference(b) // Set {1, 4}
a.isSubsetOf(b)          // false

These methods are widely supported in modern browsers.

Practical Frontend Scenarios

Use Object when:

  • Defining component props or configuration
  • Working with JSON serialization (Maps don’t serialize directly)
  • Keys are known at write time

Use Map when:

  • Keys are dynamic or user-provided (avoids prototype pollution)
  • You need object references as keys
  • Size tracking matters (map.size vs Object.keys(obj).length)
  • Building caches with frequent updates

Use Set when:

  • Tracking unique IDs or seen items
  • Deduplicating arrays: [...new Set(array)]
  • Fast membership testing

Quick Reference

FeatureObjectMapSet
Key typesstring, symbolanyN/A (values only)
SizeObject.keys().length.size.size
Iterationindirectdirectdirect
JSON supportnativemanualmanual
Prototype riskyesnono

Conclusion

The choice between Map, Set, and Object is not about which is “better”—it is about matching the data structure to your use case. Objects remain the right choice for structured data with string keys. Maps handle dynamic key-value scenarios cleanly. Sets solve uniqueness problems efficiently.

Default to objects for simplicity. Reach for Map when you need its specific capabilities. Use Set when uniqueness is your primary concern.

FAQs

Not directly. JSON.stringify does not handle Maps natively. You need to convert the Map to an array of entries first using Array.from(map) or the spread operator, then stringify that array. To restore it, parse the JSON and pass the resulting array to the Map constructor: new Map(JSON.parse(jsonString)).

Maps handle frequent insertions and deletions without the deoptimization that object property deletion can cause. They also track size natively with the size property, accept any value type as a key including DOM nodes or object references, and carry no prototype pollution risk from user-provided keys.

These methods are now widely supported in modern browsers. If you need to support older environments, check compatibility tables or use a polyfill.

Use an array when insertion order with duplicates matters, when you need index-based access, or when the collection is small enough that the overhead of a Set is not justified. For larger collections where uniqueness and fast lookups are priorities, a Set is the better choice.

Complete picture for complete understanding

Capture every clue your frontend is leaving so you can instantly get to the root cause of any issue with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.

Check our GitHub repo and join the thousands of developers in our community.

OpenReplay