2 min read

WeakMaps in JavaScript

Syed Aslam

One of the limitations in JavaScript is that the names of properties in objects must be strings. There are situations when you want to use an object or an array as a key. Unfortunately, JavaScript objects do the wrong thing, converting the key object into a key string using the

toString
method which gives us
'[object Object]'
.

With ES6, however, JavaScript gives us a second type of object called a

WeakMap
that allows objects as keys, but not strings, and with a different interface.

| Object                        | WeakMap                  |
|-------------------------------|--------------------------|
| object = Object.create(null); | weakmap = new WeakMap(); |
| object[key]                   | weakmap.get(key)         |
| object[key] = value;          | weakmap.set(key, value); |
| delete object[key];           | weakmap.delete(key);     |

WeakMaps gives you a new technique to hide private implementation data and methods from consumers of the public API you choose to expose. With WeakMaps, you can put a secret property on an object. In order to access the secret property, you need access to the object and to the secret key. You can not access the property unless you have both.

const secret_key = new WeakMap();
secret_key.set(object, secret);

secret = secret_key.get(object);

You must have access to both the object and the secret key in order to recover the secret.

The

WeakMap
does not allow inspection of its contents. You can not get a value from it unless you also hold the key.

WeakMap
interacts well with JavaScript's garbase collector. If there are no copies of the key still in existence, then that key's property in the weakmap is automatically deleted. A key object refers strongly to its contents as long as the key is not garbage collection, but weakly from the

  • does not prevent garbage collection, which eventually removes the references to the key object
  • allows garbage collection of any values if their key objects are not referenced from somewhere other than a
    WeakMap

That is, an object's presense as a key in

WeakMap
does not prevent the object from being garbase collected. Once the object used as a key has been collected, its corresponding values in any
WeakMap
become candidates for garbage collection as well - as long as they aren't strongly referred to elsewhere. This can help avoid memory leaks.

Because a

WeakMap
doesn't allow observing the liveness of its keys, its keys are not enumerable. There is no method to obtain a list of keys.

For more information and example code, see Why WeakMap? and Nick Fitzgerald's example about Hiding Implementation Details with ESMAScript 6 WeakMaps.

Also, Benjamin Gruenbaum's brilliant answer to What are the actual uses of ES6 WeakMap?

JavaScript also has a similar thing called

Map
, but
Map
does not have the security and memory leak protection that
WeakMap
has.