Path: blob/main/files/en-us/web/javascript/reference/global_objects/map/index.md
6529 views
------{{JSRef}}
The Map object holds key-value pairs and remembers the original insertion order of the keys. Any value (both objects and {{glossary("Primitive", "primitive values")}}) may be used as either a key or a value.
{{EmbedInteractiveExample("pages/js/map.html", "taller")}}
Description
Map objects are collections of key-value pairs. A key in the Map may only occur once; it is unique in the Map's collection. A Map object is iterated by key-value pairs — a {{jsxref("Statements/for...of", "for...of")}} loop returns a 2-member array of [key, value] for each iteration. Iteration happens in insertion order, which corresponds to the order in which each key-value pair was first inserted into the map by the set() method (that is, there wasn't a key with the same value already in the map when set() was called).
The specification requires maps to be implemented "that, on average, provide access times that are sublinear on the number of elements in the collection". Therefore, it could be represented internally as a hash table (with O(1) lookup), a search tree (with O(log(N)) lookup), or any other data structure, as long as the complexity is better than O(N).
Key equality
Value equality is based on the SameValueZero algorithm. (It used to use SameValue, which treated 0 and -0 as different. Check browser compatibility.) This means {{jsxref("NaN")}} is considered the same as NaN (even though NaN !== NaN) and all other values are considered equal according to the semantics of the === operator.
Objects vs. Maps
{{jsxref("Object")}} is similar to Map—both let you set keys to values, retrieve those values, delete keys, and detect whether something is stored at a key. For this reason (and because there were no built-in alternatives), Object has been used as Map historically.
However, there are important differences that make Map preferable in some cases:
| Map | Object | |
|---|---|---|
| Accidental Keys |
A Map does not contain any keys by default. It only
contains what is explicitly put into it.
|
An Note: This can be bypassed by using {{jsxref("Object.create", "Object.create(null)")}}, but this is seldom done. |
| Security |
A Map is safe to use with user-provided keys and values.
|
Setting user-provided key-value pairs on an |
| Key Types |
A Map's keys can be any value (including functions,
objects, or any primitive).
|
The keys of an Object must be either a
{{jsxref("String")}} or a {{jsxref("Symbol")}}.
|
| Key Order |
The keys in |
Although the keys of an ordinary
The order was first defined for own properties only in ECMAScript
2015; ECMAScript 2020 defines order for inherited properties as well.
See the
OrdinaryOwnPropertyKeys
and
EnumerateObjectProperties
abstract specification operations. But note that no single mechanism
iterates
all of an object's properties; the various mechanisms
each include different subsets of properties.
({{jsxref("Statements/for...in",
"for-in")}}
includes only enumerable string-keyed properties;
{{jsxref("Object.keys")}} includes only own, enumerable,
string-keyed properties;
{{jsxref("Object.getOwnPropertyNames")}} includes own,
string-keyed properties even if non-enumerable;
{{jsxref("Object.getOwnPropertySymbols")}} does the same
for just |
Size |
The number of items in a Map is easily retrieved from its
{{jsxref("Map.prototype.size", "size")}} property.
|
Determining the number of items in an Object is more roundabout and less efficient. A common way to do it is through the {{jsxref("Array/length", "length")}} of the array returned from {{jsxref("Object.keys()")}}.
|
| Iteration |
A Map is an
iterable, so it can be directly iterated.
|
Note:
|
| Performance |
Performs better in scenarios involving frequent additions and removals of key-value pairs. |
Not optimized for frequent additions and removals of key-value pairs. |
| Serialization and parsing |
No native support for serialization or parsing.
(But you can build your own serialization and parsing support for
|
Native support for serialization from {{jsxref("Object")}} to JSON, using {{jsxref("JSON.stringify()")}}. Native support for parsing from JSON to {{jsxref("Object")}}, using {{jsxref("JSON.parse()")}}. |
Setting object properties
Setting Object properties works for Map objects as well, and can cause considerable confusion.
Therefore, this appears to work in a way:
But that way of setting a property does not interact with the Map data structure. It uses the feature of the generic object. The value of 'bla' is not stored in the Map for queries. Other operations on the data fail:
The correct usage for storing data in the Map is through the set(key, value) method.
Constructor
{{jsxref("Map/Map", "Map()")}}
: Creates a new
Mapobject.
Static properties
{{jsxref("Map.@@species", "get Map[@@species]")}}
: The constructor function that is used to create derived objects.
Instance properties
These properties are defined on Map.prototype and shared by all Map instances.
{{jsxref("Object/constructor", "Map.prototype.constructor")}}
: The constructor function that created the instance object. For
Mapinstances, the initial value is the {{jsxref("Map/Map", "Map")}} constructor.
{{jsxref("Map.prototype.size")}}
: Returns the number of key/value pairs in the
Mapobject.
Map.prototype[@@toStringTag]: The initial value of the
@@toStringTagproperty is the string"Map". This property is used in {{jsxref("Object.prototype.toString()")}}.
Instance methods
{{jsxref("Map.prototype.clear()")}}
: Removes all key-value pairs from the
Mapobject.
{{jsxref("Map.prototype.delete()")}}
: Returns
trueif an element in theMapobject existed and has been removed, orfalseif the element does not exist.map.has(key)will returnfalseafterwards.
{{jsxref("Map.prototype.get()")}}
: Returns the value associated to the passed key, or
undefinedif there is none.
{{jsxref("Map.prototype.has()")}}
: Returns a boolean indicating whether a value has been associated with the passed key in the
Mapobject or not.
{{jsxref("Map.prototype.set()")}}
: Sets the value for the passed key in the
Mapobject. Returns theMapobject.
{{jsxref("Map/@@iterator", "Map.prototype@@iterator")}}
: Returns a new Iterator object that contains a two-member array of
[key, value]for each element in theMapobject in insertion order.
{{jsxref("Map.prototype.keys()")}}
: Returns a new Iterator object that contains the keys for each element in the
Mapobject in insertion order.
{{jsxref("Map.prototype.values()")}}
: Returns a new Iterator object that contains the values for each element in the
Mapobject in insertion order.
{{jsxref("Map.prototype.entries()")}}
: Returns a new Iterator object that contains a two-member array of
[key, value]for each element in theMapobject in insertion order.
{{jsxref("Map.prototype.forEach()")}}
: Calls
callbackFnonce for each key-value pair present in theMapobject, in insertion order. If athisArgparameter is provided toforEach, it will be used as thethisvalue for each callback.
Examples
Using the Map object
Using NaN as Map keys
{{jsxref("NaN")}} can also be used as a key. Even though every NaN is not equal to itself (NaN !== NaN is true), the following example works because NaNs are indistinguishable from each other:
Iterating Map with for...of
Maps can be iterated using a for...of loop:
Iterating Map with forEach()
Maps can be iterated using the {{jsxref("Map.prototype.forEach", "forEach()")}} method:
Relation with Array objects
Cloning and merging Maps
Just like Arrays, Maps can be cloned:
Note: Keep in mind that the data itself is not cloned.
Maps can be merged, maintaining key uniqueness:
Maps can be merged with Arrays, too:
Specifications
{{Specifications}}
Browser compatibility
{{Compat}}
See also
A polyfill of
Mapis available incore-js{{jsxref("Set")}}
{{jsxref("WeakMap")}}
{{jsxref("WeakSet")}}