Understanding Maps vs Objects MDN documentation


There's a question here which is similar but is specific to "when keys are unknown at runtime".

The MDN docs for Map state:

Use maps over objects when keys are unknown until run time, and when all keys are the same type and all values are the same type.

Use objects when there is logic that operates on individual elements.

I understand the advice about using maps "when keys are unknown until run time".

I'm confused by the line "when all keys are the same type and all values are the same type". What are they trying to suggest there? I mean, if all my keys are not of the same type, am I not forced to use Map anyway as it supports keys of different types? Also, why should the types of the values determine whether I use a Map or Object?

Also, I don't really understand "Use objects when there is logic that operates on individual elements." Could someone give me an example of what they mean by that?

Collections are typically homogenous. You've got a mapping from strings to numbers, from ids to objects, from usernames to User instances. All the keys have the same type, and all the value have the same type. You may select any of them for a task.

If you've got different types, you probably meant it a common "superclass" of them (in extreme, you may want Object?Object). If you didn't, that's a code smell, and likely a mistake. Especially when you have keys of different types.

In contrast, objects are meant to be used as records: a combination of fields, of fixed size. Their members are denoted by identifiers, each of them may have a different type. They are properties in JavaScript, keyed by strings or symbols. You refer to them individually, and use them for distinct purposes.


Let's see some examples.

year ? 2015
month ? 9
day ? 28

Yes, all keys are strings and all values are numbers. But we definitely don't expect to get any more or fewer of them. We use a record:

var date = {
    year: 2015,
    month: 9,
    day: 28
}
format ? "MM/DD/YYY"
monthnames ? ["January", "February", …]

Clearly, different value types. And we will use them individually. So again, an object:

var locale_en = {
    format: "MM/DD/YYY",
    monthnames: ["January", "February", …]
};
en ? locale_en
de ? locale_de
fr ? locale_fr
…

This is clearly a different one. Notice the ellipsis? There could be more. And all keys are language codes, and all values are locales. When using them, we'll just use one of many. This is a collection:

var locales = new Map([
    ["en", locale_en],
    ["de", locale_de],
    …
]);