The Map object is a simple key/value map. Any value (both objects and primitive values) may be used as either a key or a value.
> var animalSounds = new Map();
> animalSounds.set("dog", "woof");
Map {"dog" => "woof"}
> animalSounds.set("cat", "meow");
Map {"dog" => "woof", "cat" => "meow"}
> animalSounds.set("frog", "ribbit");
Map {"dog" => "woof", "cat" => "meow", "frog" => "ribbit"}
> console.log(animalSounds.size);
3
> console.log(animalSounds.has("dog"));
true
> animalSounds.delete("dog");
true
> console.log(animalSounds.size);
2
> console.log(animalSounds.has("dog"));
false
> animalSounds.clear();
> console.log(animalSounds.size);
0
Objects are similar to Maps in that both let you...
- set keys to values,
- retrieve those values,
- delete keys,
- and detect whether something is stored at a key.
However, there are important differences between Objects and Maps that make using a Map better:
- An Object has a prototype, so there are default keys in the map. Maps doesn't have default values
- The keys of an Object are
Strings
andSymbols
, where they can be any value for a Map (other objects for example). - You can get the
size
of a Map easily while you have to manually keep track of size for an Object.
Signs that you want a Map for a collection:
- Are keys usually unknown until run time, do you need to look them up dynamically?
- Do all values have the same type, and can be used interchangeably?
- Do you need keys that aren't strings?
- Are key-value pairs often added or removed?
- Do you have an arbitrary (easily changing) amount of key-value pairs? Is the collection iterated?
If in contrast you have a fixed amount of keys, operate on them individually, and distinguish between their usage, then you want an object.
> var myMap = new Map();
> var keyString = "a string",
keyObj = {},
keyFunc = function () {};
> myMap.set(keyString, "value associated with 'a string'");
> myMap.set(keyObj, "value associated with keyObj");
> myMap.set(keyFunc, "value associated with keyFunc");
> myMap.size;
3
> myMap.get(keyString);
"value associated with 'a string'"
> myMap.get(keyObj);
"value associated with keyObj"
> myMap.get(keyFunc);
"value associated with keyFunc"
> myMap.get("a string");
"value associated with 'a string'"
> myMap.get({}); // undefined, because keyObj !== {}
undefined
> myMap.get(function() {}) // undefined, because keyFunc !== function () {}
undefined
> var myMap = new Map();
> myMap.set(0, "zero");
> myMap.set(1, "one");
> for (var [key, value] of myMap) {
console.log(key + " = " + value);
}
0 = zero
1 = one
> for (var key of myMap.keys()) {
console.log(key);
}
0
1
> for (var value of myMap.values()) {
console.log(value);
}
zero
one
> for (var [key, value] of myMap.entries()) {
console.log(key + " = " + value);
}
0 = zero
1 = one
> myMap.forEach(function(value, key) {
console.log(key + " = " + value);
}, myMap)
0 = zero
1 = one
More info: