Any point in using ES6 Map when keys are all strings?
https://softwareengineering.stackexchange.com/questions/285881
-
08-10-2020 - |
Question
Plain object keys must be strings, whereas a Map
can have keys of any type.
But I have little use for this in practice. In nearly all cases, I find myself using strings as keys anyway. And presumably new Map()
is slower than {}
. So is there any other reason why it might be better to use a Map
instead of a plain object?
Solution
There are some reasons why I prefer using Map
s over plain objects ({}
) for storing runtime data (caches, etc):
- The
.size
property lets me know how many entries exist in this Map; - The various utility methods -
.clear()
,.forEach()
, etc; - They provide me iterators by default!
Every other case, like passing function arguments, storing configurations and etc, are all written using plain objects.
Also, remember: Don't try to optimize your code too early. Don't waste your time doing benchmarks of plain object vs Maps unless your project is suffering performance problems.
OTHER TIPS
I'm not sure about this, but I think that performance is NOT a reason to use Maps. Take a look at this updated jsperf page:
http://jsperf.com/es6-map-vs-object-properties/73
It looks like (when dealing with strings at least) objects are much faster than maps for basic setting and getting.
EDIT: this answer is now outdated and wrong. See comment stream below.
EDIT2: Oddly, after all of the comments, it seems to return to Object being faster than Map (at least when storing numeric values). https://jsperf.com/es6-map-vs-object-properties/243
The other answers don't mention one last difference between objects and Map
s:
The
Map
object holds key-value pairs and remembers the original insertion order of the keys.Thus, when iterating over it, a Map object returns keys in order of insertion.
Quote from MDN, emphasis mine
This was the main reason I decided to use Map
for the first time in a recent project. I had a normal object that I needed to display in a <table>
, with each property going in a specific row.
let productPropertyOrder = [ "name", "weight", "price", "stocked" ];
let product =
{
name: "Lasagne",
weight: "1kg",
price: 10,
stocked: true
}
I wrote a function to transform an object into a Map
according to a desired key order:
Note: this function discards all object properties not found in
order
function objectToMap( obj, order )
{
let map = new Map();
for ( const key of order )
{
if ( obj.hasOwnProperty( key ) )
{
map.set( key, obj[ key ] );
}
}
return map;
}
Then the map could be iterated over in the desired order:
let productMap = objectToMap( product, productPropertyOrder );
for ( const value of productMap.values() )
{
let cell = document.createElement( "td" );
cell.innerText = value;
row.appendChild( cell );
}
Of course this is a bit contrived because one could just as well display when iterating over the property order without creating a Map
in the process:
for ( const key of productPropertyOrder )
{
if ( product.hasOwnProperty( key ) )
{
let value = product[ key ];
// create cell
}
}
But if you have an array of such objects and are going to be displaying them many places, then converting them all to maps first makes sense.