JavaScript Map and WeakMap
This is the second part of a two post series. The first one was JavaScript Set and WeakSet.
Map
From MDN: 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.
Maps are like regular Objects if you treat them as a dictionary (key-value map). But if you notice, anything can be a key on a Map
, even objects or other maps.
Just like the Set
, the Map
implementation stores their elements in insertion order. So, for..of
loop will return a [key, value]
for every iteration in that order.
var DoctorEleven = {};
var SonicScrewdriverEleven = {};
var DoctorsSonicScrewdriver = new Map();
DoctorsSonicScrewdriver.set(DoctorEleven, SonicScrewdriverEleven);
var myMap = new Map();
myMap.set(NaN, "Oh!");
myMap.set(0, "zero");
myMap.set(1, "one");
for (var [key, value] of myMap) {
console.log(key + " = " + value);
}
Maps
are like Objects, and of course they are since we been using Objects
to store values as the were Maps since the beginning. So, why change now?
-
Object
keys have to always bestrings
, where they can be any type of value onMap
. -
You can easily get the amount of elements in your
Map
, inObject
you will have to create that functionality for every instance. -
Equality is been check using the
SameValueZero
comparison algorithm. -
There are default keys in an Object since their prototype.
Map
doesn't inherit this behaviour, making them a little "cleaner".Map.prototype
has the attributesWritable
,Enumerable
andConfigurable
set tofalse
to ensure this.
The Map
constructor
In the ECMAScript Specification, explains that Maps
are designed to be subclassable. Meaning that you can inherit one Map
from another.
You can set an iterator on the Map
constructor. The iterator has to produce an two elements structure (like array of arrays). The first element will be the key for the Map
element, and the second his value.
var mapA = new Map();
mapA.set('hey', 'you!');
console.log(mapA.get('hey'));
>> 'you!'
var mapB = new Map(mapA);
console.log(mapB.get('hey'));
>> 'you!'
Another option could be to simply pass an array. Like [[key1, val1], [key2, val2], ...]
.
var mapB = new Map([['hey', 'you!']]);
console.log(mapB.get('hey'));
>> 'you!'
The last example will produce exactly the same results as the previous one.
List of methods and properties
Name | Description |
---|---|
size |
Return the number of elements in the Map. |
add(key, value) |
Sets the value for the key in the Map object. Returns the Map object. |
get(key) |
Returns the value associated to the key, or undefined if there is none. |
clear() |
Removes all elements. |
delete(value) |
Removes the element associated. |
entries() |
Returns a new Iterator object that contains an array of [key, value] for each element in the Map object in insertion order. |
forEach(callback) |
Regular forEach . |
has(value) |
Returns true if the key is in the Map, false if it isn't. |
values() |
Returns a new Iterator object with the values of each element in the Map. |
keys() |
Returns a new Iterator object that contains the keys for each element in the Map object in insertion order. |
WeakMap
Analogous to the WeakSet
, the WeakMap
keys can only be Object
. Primitive data types aren't allowed here.
References to the objects key are weakly attached. This won't prevent the garbage collector to delete them if they're only referenced here.
Thanks to this, the keys on the WeakMap
are not iterable. If you'd like a list of the keys, you'll have to store it by yourself.
The value of .length
will always be 0.
List of methods and properties
Name | Description |
---|---|
delete(key) |
Removes any value associated to the key. |
has(key) |
Returns true if the key exists on the Map or false if it doesn't. |
get(key) |
Returns the value of the key or undefined. |
set(key, value) |
Sets the value for the key in the WeakMap object. Returns the WeakMap object. |
Cool uses
Nick Fitzgerald introduces a techinque for hiding private implementations using WeakMaps
in his blog.
He saids that "The WeakMap privates pattern is the best choice when you really need to hide private implementation details from public API consumers."
Subscribe to RECodes
Get the latest posts delivered right to your inbox