Any point in using ES6 Map when keys are all strings?
https://softwareengineering.stackexchange.com/questions/285881
-
08-10-2020 - |
문제
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?
해결책
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.
다른 팁
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.