More About Maps

Previously I talked about the value of the new Map() object which was introduced in ES6. It’s darned exciting (well to those of us who get excited by new Javascript features), but there’s a little more to it than just get() and set(). Over the years a number of nice functional features have crept into Javascript (some inspired by UnderscoreJS or jQuery). Thus you have some nice features on arrays that allow you to iterate through them, apply functions to each element, or even do reductions. As you might expect, a lot of similar capabilities are available with the new Map objects. They’ve got a number of useful functions besides just get and set. But first the basics. First we’ll set up a new map and put stuff in it:

x = new Map();
x.set('a', '1');
x.set('b', '2');
x.set('c', '3');

Now if you examine x, you’ll see the Map object with those entries:

> Map {"a" => 1, "b" => 2, "c" => 3}

and if you use the get function you should see:

> "2"

If you try to get with a key that it doesn’t have, you’ll get undefined:

 > undefined

But, to add to the confusion, you’ll get the same thing if the key is there but it’s value is 'undefined':

x.set('d', undefined);
> undefined

If you really want to tell whether the map contains an entry with a given key, you'd use the has function:

> true
> false

When you delete an entry, you might notice that it has a return value of either true or false. true means that there was an entry with that key and it was deleted. false means there was no entry with that key (same as running has() just before deletion).

> true

clear deletes all the entries in x, leaving you with a Map that's just like new:

> undefined
> Map {}

There's a few other interesting ones, like values() and keys(), which return iterators listing all of the values and keys respectively, in the order in which they were added. entries() will return iterators containing all the entries as a 2 element array, first the key, then the value.

Finally, if you want to step through the Map Object in a loop, you can use the foreach function:

x.foreach(function(v,k) {console.log(v,k)})
1 a
2 b
3 c

It's just slightly confusing because the parameters to the function called by foreach are backwards from most other uses. I think this is because they expect it's more common to loop through all the values without the keys than the other way round. You just need to remember which way it goes.

To get into more detail on these functions I'd want to dive into iterators, but I'll save that for another time. The MDN page recommends Maps over objects in a number of different situations and has a number of other gory details. It's worth a quick read.