Map is an ECMAScript 2015 feature that allows storing key-value pairs in a
collection, similar to plain objects, but with a few “advantages” such as:
- The keys can be of any type, not just strings (even other
- The keys are ordered.
- It includes a bunch of methods to manipulate the collection.
It is a great tool but, sadly, an overly used one, and more often than not, it can or should be replaced by a plain object or an array.
I wrote this first because, from my point of view, this is one of the most
important reasons to avoid
Map. One of the main advantages of using plain
However, we can’t serialize
Map as JSON, nor can we parse it from JSON
directly. This limitation means we need to use extra steps or libraries to
Map when working with JSON data.
For example, if we have a
Map object like this:
We cannot simply use
JSON.stringify to convert it to JSON:
Instead, we need to convert the Map object to an array of key-value pairs first:
Similarly, if we have a JSON string like this:
We cannot simply use
JSON.parse to convert it to a
Instead, we need to pass the parsed
Array to the
These extra steps are cumbersome, verbose, and prone to errors and inconsistencies. For example, if we have nested Maps or other non-serializable values in our Map object, we must handle them separately or use custom replacer and reviver functions.
On the other hand, plain objects can be easily serialized and parsed as JSON without any extra steps or libraries:
So this makes plain objects much more convenient and reliable for working with data serialization.
Another disadvantage of using Map objects is that they have a different syntax for accessing values than plain objects. To get a value from a Map object by its key, we need to use the get method:
However, to get a value from a plain object by its key, we can use dot notation or bracket notation:
This is picky, until we consider that we also need to write stuff like deconstructing differently:
Or if we want to get more than one value:
And for spread syntax:
We are sacrificing a lot of readability and consistency just for the sake of
Staying on the topic of syntax, creating a new
Map with data on it is also
less readable than creating a plain object:
Meanwhile, to create a new plain object, we can use curly braces and comma-separated key-value pairs:
I’m not a person that usually makes this argument. I would take something
readable over something performant any day. But in this case, we have already
proven that readability could be better, and performance could be better too.
This point is not a surprise if we compare plain objects with objects that
include methods (
has, etc.) and state (
size, the key-value
Of course, there may be some cases where Maps have better performance than plain
objects, such as when using non-string keys or when iterating over extensive
collections. However, these cases are rare and specific and do not justify using
Map over plain objects in general.
Map favors mutation. We can work with “immutable
Map,” but then the
performance suffers even more. So when working with architectures based on
immutability, such as React,
Map becomes even less compelling. I already
wrote about the problems introduced by mutation and
how to avoid them, so I’ll no go into details. We can achieve an immutable
Map, but for that to be performant, we need libraries such as Immer,
and at that point, we are just adding even more complexity to our code.
One common argument favoring
Map is that it has ordered key-value pairs, while
plain objects can’t guarantee that. However, my point generally is: If we are
have had it for a long time, and it’s called
For the most part, we can replace
Map with plain objects and get the same
results with less and more readable and maintainable code with better
Map has its uses. It can be an excellent tool for handling some types of
structures in memory in some scenarios, but my rule of thumb generally is to use
it only when we need to use non-string keys for some reason (tho, more often
than not, an array of tuples are good enough).