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.
const person = { name: 'John', age: 30, occupation: 'Developer' };console.log(person);
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.
const person = new Map([['name', 'John'],['age', 30],['occupation', 'Developer'],]);console.log(person);
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.