What is the difference between a `Map` object and a plain object in JavaScript?
TL;DR
Both Map objects and plain objects in JavaScript can store key-value pairs, but they have several key differences:
| Feature | Map | Plain object |
|---|---|---|
| Key type | Any data type | String (or Symbol) |
| Key order | Insertion order | Defined own-key order; integer-index keys come first, then other strings by insertion order, then symbols |
| Size property | Yes (size) | None |
| Iteration | forEach, keys(), values(), entries() | for...in, Object.keys(), etc. |
| Prototype interaction | User keys do not collide with Map.prototype methods | Object literals inherit from Object.prototype unless created with a null prototype |
| Performance | Designed for frequent keyed additions/removals; measure for the actual workload | Often convenient for fixed records; measure for the actual workload |
| JSON | Entries need an explicit conversion or replacer | Own enumerable string-keyed data is handled by JSON.stringify(), subject to JSON's normal limitations |
Map vs plain JavaScript objects
In JavaScript, Map objects and plain objects (also known as a "POJO" or "plain old JavaScript object") are both used to store key-value pairs, but they have different characteristics, use cases, and behaviors.
Plain JavaScript objects (POJO)
A plain object is a basic JavaScript object created using the {} syntax. It is a collection of key-value pairs, where each key is a string (or a symbol, in modern JavaScript) and each value can be of any type, including strings, numbers, booleans, arrays, objects, and more.
Map objects
A Map object, introduced in ECMAScript 2015 (ES6), is a more advanced data structure that allows you to store key-value pairs with additional features. A Map is an iterable, which means you can use it with for...of loops, and it provides methods for common operations like get, set, has, and delete.
Key differences
Here are the main differences between a Map object and a plain object:
- Key types: In a plain object, keys are always strings (or symbols). In a
Map, keys can be any type of value, including objects, arrays, and even otherMaps. - Key ordering: Both have specified ordering rules.
Mapiteration follows insertion order. Object own keys put integer-index keys first in numeric order, then other string keys in insertion order, then symbol keys in insertion order; individual enumeration APIs select different subsets of those keys. - Iteration: A
Mapis iterable, which means you can usefor...ofloops to iterate over its key-value pairs. A plain object is not iterable by default, but you can useObject.keys()orObject.entries()to iterate over its properties. - Performance:
Mapis designed for dynamic keyed collections and frequent additions and removals. Plain objects can be excellent for fixed-shape records. Performance depends on the engine and workload, so benchmark before choosing solely for speed. - Methods: A
Mapobject provides additional methods, such asget,set,has, anddelete, which make it easier to work with key-value pairs. - Serialization:
JSON.stringify()does not serialize aMap's entries; it produces an empty object ({}) because the entries are not own enumerable properties. A plain object, on the other hand, is serialized to a JSON object with the same structure.
When to use which
Use a plain object (POJO) when:
- You need a simple, lightweight object with string keys.
- The keys describe a record with a known shape.
- You need to serialize the object to JSON (e.g. to send over the network).
Use a Map object when:
- You need to store key-value pairs with non-string keys (e.g., objects, arrays).
- You need to preserve the order of key-value pairs.
- You need to iterate over the key-value pairs in a specific order.
- You frequently add or remove arbitrary keys and the measured workload favors
Map.
Use plain objects for record-like data and Map for general-purpose keyed collections. Neither is universally faster or more capable; key types, iteration, prototype behavior, and serialization are usually better decision criteria.
Notes
JSON.stringify(new Map([['a', 1]])) produces {} because map entries are not enumerable object properties. Convert with Object.fromEntries(map) when keys are JSON-safe strings, serialize an entry array with [...map], provide a replacer, or use a library with explicit Map support.