24.4 WeakSet Objects

WeakSet objects are collections of objects. A distinct object may only occur once as an element of a WeakSet's collection. A WeakSet may be queried to see if it contains a specific object, but no mechanism is provided for enumerating the objects it holds. In certain conditions, objects which are not live are removed as WeakSet elements, as described in 9.9.3.

An implementation may impose an arbitrarily determined latency between the time an object contained in a WeakSet becomes inaccessible and the time when the object is removed from the WeakSet. 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 determine if a WeakSet contains a particular object that does not require the observer to present the observed object.

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

Note

See the NOTE in 24.3.

24.4.1 The WeakSet Constructor

The WeakSet constructor:

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

24.4.1.1 WeakSet ( [ iterable ] )

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

  1. If NewTarget is undefined, throw a TypeError exception.
  2. Let set be ? OrdinaryCreateFromConstructor(NewTarget, "%WeakSet.prototype%", « [[WeakSetData]] »).
  3. Set set.[[WeakSetData]] to a new empty List.
  4. If iterable is either undefined or null, return set.
  5. Let adder be ? Get(set, "add").
  6. If IsCallable(adder) is false, throw a TypeError exception.
  7. Let iteratorRecord be ? GetIterator(iterable).
  8. Repeat,
    1. Let next be ? IteratorStep(iteratorRecord).
    2. If next is false, return set.
    3. Let nextValue be ? IteratorValue(next).
    4. Let status be Call(adder, set, « nextValue »).
    5. If status is an abrupt completion, return ? IteratorClose(iteratorRecord, status).

24.4.2 Properties of the WeakSet Constructor

The WeakSet constructor:

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

24.4.2.1 WeakSet.prototype

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

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

24.4.3 Properties of the WeakSet Prototype Object

The WeakSet prototype object:

24.4.3.1 WeakSet.prototype.add ( value )

The following steps are taken:

  1. Let S be the this value.
  2. Perform ? RequireInternalSlot(S, [[WeakSetData]]).
  3. If Type(value) is not Object, throw a TypeError exception.
  4. Let entries be the List that is S.[[WeakSetData]].
  5. For each element e of entries, do
    1. If e is not empty and SameValue(e, value) is true, then
      1. Return S.
  6. Append value as the last element of entries.
  7. Return S.

24.4.3.2 WeakSet.prototype.constructor

The initial value of WeakSet.prototype.constructor is the %WeakSet% intrinsic object.

24.4.3.3 WeakSet.prototype.delete ( value )

The following steps are taken:

  1. Let S be the this value.
  2. Perform ? RequireInternalSlot(S, [[WeakSetData]]).
  3. If Type(value) is not Object, return false.
  4. Let entries be the List that is S.[[WeakSetData]].
  5. For each element e of entries, do
    1. If e is not empty and SameValue(e, value) is true, then
      1. Replace the element of entries whose value is e with an element whose value is empty.
      2. 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.4.3.4 WeakSet.prototype.has ( value )

The following steps are taken:

  1. Let S be the this value.
  2. Perform ? RequireInternalSlot(S, [[WeakSetData]]).
  3. Let entries be the List that is S.[[WeakSetData]].
  4. If Type(value) is not Object, return false.
  5. For each element e of entries, do
    1. If e is not empty and SameValue(e, value) is true, return true.
  6. Return false.

24.4.3.5 WeakSet.prototype [ @@toStringTag ]

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

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

24.4.4 Properties of WeakSet Instances

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