32

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?

  • 3
    MDN, as usual, has a good comparison. – Chris Hayes Jun 5 '15 at 2:18
  • 1
    FYI, Map appears to be faster for both setting and getting. – mpen Feb 2 '16 at 17:46
  • @mpen – jsperf is down now. Are you sure map.set('foo', 123) performed quicker than obj.foo = 123? If so that's very surprising – callum Sep 22 '16 at 16:14
  • @callum Uhh..no, not positive. You might want to write some new performance tests. – mpen Sep 22 '16 at 16:38
40

There are some reasons why I prefer using Maps over plain objects ({}) for storing runtime data (caches, etc):

  1. The .size property lets me know how many entries exist in this Map;
  2. The various utility methods - .clear(), .forEach(), etc;
  3. 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.

4

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.

  • 2
    That's not how you write performance tests. – Qix Aug 5 '17 at 22:00
  • 5
    That's not how you write useful comments. Please feel free to elaborate if you have an alternate methodology to suggest. What, specifically, is wrong with how those tests were written? Are they in any way invalid or unhelpful? – starlogodaniel Aug 7 '17 at 18:38
  • 7
    Language semantics/constructs being tested via microbenchmarks must only differ by one variable. Your tests vary across number of iterations, and a few of them will have their inner loop contents optimized out since the result is unused. Some tests pre-declare variables while others have the variable declaration inline with the for loop - which may incur different performance abnormalities. – Qix Aug 8 '17 at 5:38
  • 1
    Ouch, you're absolutely right. In my defense, the my version was an improvement on the one before it, but I missed both the pre-declare and the inner loop contents being optimized out. I was working with a colleague who improved upon my draft and I think resolved those issues: jsperf.com/es6-map-vs-object-properties/88. However, I think that it's valid to have different loop styles for the different data structures; in real usage, people will choose the loop structure with the best performance, and Map and Object have different "optimal" loop structures. Anyway, thanks for the catch. – starlogodaniel Aug 9 '17 at 15:12
  • So maps are actually faster? :o Or what is conclusion here? – jayarjo Jun 8 '18 at 17:34
0

The other answers don't mention one last difference between objects and Maps:

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:

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.

protected by gnat Mar 17 at 10:24

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.