WeakSet

The WeakSet object lets you store weakly held objects in a collection.

Description

WeakSet objects are collections of objects. Just as with Sets, each object in a WeakSet may occur only once; all objects in a WeakSet's collection are unique.

The main differences to the Set object are:

  • WeakSets are collections of objects only. They cannot contain arbitrary values of any type, as Sets can.
  • The WeakSet is weak, meaning references to objects in a WeakSet are held weakly. If no other references to an object stored in the WeakSet exist, those objects can be garbage collected.
    • Note: This also means that there is no list of current objects stored in the collection. WeakSets are not enumerable.

Use case: Detecting circular references

Functions that call themselves recursively need a way of guarding against circular data structures by tracking which objects have already been processed.

WeakSets are ideal for this purpose:

// Execute a callback on everything stored inside an object
function execRecursively(fn, subject, _refs = null){
	if(!_refs)
		_refs = new WeakSet();
	
	// Avoid infinite recursion
	if(_refs.has(subject))
		return;

	fn(subject);
	if("object" === typeof subject){
		_refs.add(subject);
		for(let key in subject)
			execRecursively(fn, subject[key], _refs);
	}
}

const foo = {
	foo: "Foo",
	bar: {
		bar: "Bar"
	}
};

foo.bar.baz = foo; // Circular reference!
execRecursively(obj => console.log(obj), foo);

Here, a WeakSet is created on the first run, and passed along with every subsequent function call (using the internal _refs parameter).

The number of objects or their traversal order is immaterial, so a WeakSet is more suitable (and performant) than a Set for tracking object references, especially if a very large number of objects is involved.

Constructor

WeakSet()
Creates a new WeakSet object.

Instance methods

WeakSet.prototype.add(value)
Appends value to the WeakSet object.
WeakSet.prototype.delete(value)
Removes value from the WeakSet. WeakSet.prototype.has(value) will return false afterwards.
WeakSet.prototype.has(value)
Returns a boolean asserting whether value is present in the WeakSet object or not.

Examples

Using the WeakSet object

const ws = new WeakSet();
const foo = {};
const bar = {};

ws.add(foo);
ws.add(bar);

ws.has(foo);    // true
ws.has(bar);    // true

ws.delete(foo); // removes foo from the set
ws.has(foo);    // false, foo has been removed
ws.has(bar);    // true, bar is retained

Note that foo !== bar. While they are similar objects, they are not the same object. And so they are both added to the set.

Specifications

Specification
ECMAScript (ECMA-262)
The definition of 'WeakSet' in that specification.

Browser compatibility

DesktopMobileServer
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome for AndroidFirefox for AndroidOpera for AndroidSafari on iOSSamsung InternetNode.js
WeakSetChrome Full support 36Edge Full support 12Firefox Full support 34IE No support NoOpera Full support 23Safari Full support 9WebView Android Full support 37Chrome Android Full support 36Firefox Android Full support 34Opera Android Full support 24Safari iOS Full support 9Samsung Internet Android Full support 3.0nodejs Full support 0.12
WeakSet() constructorChrome Full support 36Edge Full support 12Firefox Full support 34IE No support NoOpera Full support 23Safari Full support 9WebView Android Full support 37Chrome Android Full support 36Firefox Android Full support 34Opera Android Full support 24Safari iOS Full support 9Samsung Internet Android Full support 3.0nodejs Full support 0.12
addChrome Full support 36Edge Full support 12Firefox Full support 34IE No support NoOpera Full support 23Safari Full support 9WebView Android Full support 37Chrome Android Full support 36Firefox Android Full support 34Opera Android Full support 24Safari iOS Full support 9Samsung Internet Android Full support 3.0nodejs Full support 0.12
clear
DeprecatedNon-standard
Chrome No support 36 — 43Edge No support NoFirefox No support 34 — 46IE No support NoOpera No support 25 — 30Safari No support NoWebView Android No support 37 — 43Chrome Android No support 36 — 43Firefox Android No support 34 — 46Opera Android No support 25 — 30Safari iOS No support NoSamsung Internet Android No support 3.0 — 4.0nodejs No support No
deleteChrome Full support 36Edge Full support 12Firefox Full support 34IE No support NoOpera Full support 23Safari Full support 9WebView Android Full support 37Chrome Android Full support 36Firefox Android Full support 34Opera Android Full support 24Safari iOS Full support 9Samsung Internet Android Full support 3.0nodejs Full support 0.12
hasChrome Full support 36Edge Full support 12Firefox Full support 34IE No support NoOpera Full support 23Safari Full support 9WebView Android Full support 37Chrome Android Full support 36Firefox Android Full support 34Opera Android Full support 24Safari iOS Full support 9Samsung Internet Android Full support 3.0nodejs Full support 0.12

Legend

Full support
Full support
No support
No support
Non-standard. Expect poor cross-browser support.
Non-standard. Expect poor cross-browser support.
Deprecated. Not for use in new websites.
Deprecated. Not for use in new websites.

See also