24.3 WeakMap Objects

WeakMaps are collections of key/value pairs where the keys are objects and values may be arbitrary ECMAScript language values. A WeakMap may be queried to see if it contains a key/value pair with a specific key, but no mechanism is provided for enumerating the objects it holds as keys. In certain conditions, objects which are not live are removed as WeakMap keys, as described in 9.10.3.

An implementation may impose an arbitrarily determined latency between the time a key/value pair of a WeakMap becomes inaccessible and the time when the key/value pair is removed from the WeakMap. If this latency was observable to ECMAScript program, it would be a source of indeterminacy that could impact program execution. For that reason, an ECMAScript implementation must not provide any means to observe a key of a WeakMap that does not require the observer to present the observed key.

WeakMaps must be implemented using either hash tables or other mechanisms that, on average, provide access times that are sublinear on the number of key/value pairs in the collection. The data structure used in this specification is only intended to describe the required observable semantics of WeakMaps. It is not intended to be a viable implementation model.

Note

WeakMap and WeakSets are intended to provide mechanisms for dynamically associating state with an object in a manner that does not “leak” memory resources if, in the absence of the WeakMap or WeakSet, the object otherwise became inaccessible and subject to resource reclamation by the implementation's garbage collection mechanisms. This characteristic can be achieved by using an inverted per-object mapping of weak map instances to keys. Alternatively each weak map may internally store its key to value mappings but this approach requires coordination between the WeakMap or WeakSet implementation and the garbage collector. The following references describe mechanism that may be useful to implementations of WeakMap and WeakSets:

Barry Hayes. 1997. Ephemerons: a new finalization mechanism. In Proceedings of the 12th ACM SIGPLAN conference on Object-oriented programming, systems, languages, and applications (OOPSLA '97), A. Michael Berman (Ed.). ACM, New York, NY, USA, 176-183, http://doi.acm.org/10.1145/263698.263733.

Alexandra Barros, Roberto Ierusalimschy, Eliminating Cycles in Weak Tables. Journal of Universal Computer Science - J.UCS, vol. 14, no. 21, pp. 3481-3497, 2008, http://www.jucs.org/jucs_14_21/eliminating_cycles_in_weak

24.3.1 The WeakMap Constructor

The WeakMap constructor:

  • is %WeakMap%.
  • is the initial value of the "WeakMap" property of the global object.
  • creates and initializes a new WeakMap when called as a constructor.
  • is not intended to be called as a function and will throw an exception when called in that manner.
  • may be used as the value in an extends clause of a class definition. Subclass constructors that intend to inherit the specified WeakMap behaviour must include a super call to the WeakMap constructor to create and initialize the subclass instance with the internal state necessary to support the WeakMap.prototype built-in methods.

24.3.1.1 WeakMap ( [ iterable ] )

When the WeakMap function is called with optional argument iterable, the following steps are taken:

  1. If NewTarget is undefined, throw a TypeError exception.
  2. Let map be ? OrdinaryCreateFromConstructor(NewTarget, "%WeakMap.prototype%", « [[WeakMapData]] »).
  3. Set map.[[WeakMapData]] to a new empty List.
  4. If iterable is either undefined or null, return map.
  5. Let adder be ? Get(map, "set").
  6. Return ? AddEntriesFromIterable(map, iterable, adder).
Note

If the parameter iterable is present, it is expected to be an object that implements an @@iterator method that returns an iterator object that produces a two element array-like object whose first element is a value that will be used as a WeakMap key and whose second element is the value to associate with that key.

24.3.2 Properties of the WeakMap Constructor

The WeakMap constructor:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has the following properties:

24.3.2.1 WeakMap.prototype

The initial value of WeakMap.prototype is the WeakMap prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

24.3.3 Properties of the WeakMap Prototype Object

The WeakMap prototype object:

24.3.3.1 WeakMap.prototype.constructor

The initial value of WeakMap.prototype.constructor is %WeakMap%.

24.3.3.2 WeakMap.prototype.delete ( key )

The following steps are taken:

  1. Let M be the this value.
  2. Perform ? RequireInternalSlot(M, [[WeakMapData]]).
  3. Let entries be the List that is M.[[WeakMapData]].
  4. If Type(key) is not Object, return false.
  5. For each Record { [[Key]], [[Value]] } p of entries, do
    1. If p.[[Key]] is not empty and SameValue(p.[[Key]], key) is true, then
      1. Set p.[[Key]] to empty.
      2. Set p.[[Value]] to empty.
      3. Return true.
  6. Return false.
Note

The value empty is used as a specification device to indicate that an entry has been deleted. Actual implementations may take other actions such as physically removing the entry from internal data structures.

24.3.3.3 WeakMap.prototype.get ( key )

The following steps are taken:

  1. Let M be the this value.
  2. Perform ? RequireInternalSlot(M, [[WeakMapData]]).
  3. Let entries be the List that is M.[[WeakMapData]].
  4. If Type(key) is not Object, return undefined.
  5. For each Record { [[Key]], [[Value]] } p of entries, do
    1. If p.[[Key]] is not empty and SameValue(p.[[Key]], key) is true, return p.[[Value]].
  6. Return undefined.

24.3.3.4 WeakMap.prototype.has ( key )

The following steps are taken:

  1. Let M be the this value.
  2. Perform ? RequireInternalSlot(M, [[WeakMapData]]).
  3. Let entries be the List that is M.[[WeakMapData]].
  4. If Type(key) is not Object, return false.
  5. For each Record { [[Key]], [[Value]] } p of entries, do
    1. If p.[[Key]] is not empty and SameValue(p.[[Key]], key) is true, return true.
  6. Return false.

24.3.3.5 WeakMap.prototype.set ( key, value )

The following steps are taken:

  1. Let M be the this value.
  2. Perform ? RequireInternalSlot(M, [[WeakMapData]]).
  3. Let entries be the List that is M.[[WeakMapData]].
  4. If Type(key) is not Object, throw a TypeError exception.
  5. For each Record { [[Key]], [[Value]] } p of entries, do
    1. If p.[[Key]] is not empty and SameValue(p.[[Key]], key) is true, then
      1. Set p.[[Value]] to value.
      2. Return M.
  6. Let p be the Record { [[Key]]: key, [[Value]]: value }.
  7. Append p as the last element of entries.
  8. Return M.

24.3.3.6 WeakMap.prototype [ @@toStringTag ]

The initial value of the @@toStringTag property is the String value "WeakMap".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

24.3.4 Properties of WeakMap Instances

WeakMap instances are ordinary objects that inherit properties from the WeakMap prototype. WeakMap instances also have a [[WeakMapData]] internal slot.