WeakMap and WeakSet

Learn what WeakMap and WeakSet are in JavaScript, how they differ from Map and Set, and when to use them. Includes syntax, methods, and use cases.

Loading...
WeakMap and WeakSet

In JavaScript, objects and arrays are often used to store and manage data.

But JavaScript also provides four powerful built-in data structures that are often more useful and efficient than plain objects or arrays when you need uniqueness or flexible key types.

  • WeakSet
  • WeakMap
  • Set
  • Map

Let’s learn about each one in detail.

WeakSet in JavaScript

A WeakSet is similar to a Set, but it only stores objects and is not iterable.

If you store an object inside a regular structure like an array, Set, or Map, that object is strongly referenced. This means as long as it's stored there, JavaScript won’t remove it from memory, even if your code no longer uses it.

But items in WeakSet hold weak references. This means they don’t prevent garbage collection. If there are no other references to an object (other than being in a WeakSet), the JavaScript engine is free to automatically delete it from memory.

Creating a WeakSet

You can create a WeakSet by using new WeakSet() syntax.

const ws = new WeakSet();
 
console.log(ws); // Output: WeakSet []

WeakSet Methods

JavaScript provides the following methods to work with WeakSet.

add(object):

The add(object) method adds an object to the WeakSet.

const ws = new WeakSet();
const user = { id: 1 };
 
ws.add(user);

If you later remove all other references to user, it can be automatically removed from memory.

has(object):

The has(object) method returns true if an object exists in the WeakSet.

ws.has(user); // Output: true

delete(object):

The delete(object) method removes the object from the WeakSet.

ws.delete(user); // Output: true

Limitations of WeakSet

  • Only works with objects (not primitives).
  • You can’t loop over a WeakSet.
  • No .size, .clear(), or .forEach().

Use Case of WeakSet

WeakSet is useful for tracking objects privately.

const visitedNodes = new WeakSet();
 
function markVisited(node) {
  if (!visitedNodes.has(node)) {
    visitedNodes.add(node);
    console.log("Processing:", node.name);
  }
}
 
const nodeA = { name: "Node A" };
const nodeB = { name: "Node B" };
 
markVisited(nodeA); // Output: Processing: Node A
markVisited(nodeB); // Output: Processing: Node B
markVisited(nodeA); // No output

Here,

  • You create a WeakSet to track objects (in this case, nodeA and nodeB).
  • A WeakSet only allows objects (not primitives) and holds weak references, meaning it won’t prevent garbage collection.
  • function markVisited(node) {...} checks whether the node has already been processed (i.e., is in visitedNodes). If not, it:
    • Adds it to the WeakSet (so next time it won't be processed again)
    • Logs the message
  • nodeA and nodeB are just plain objects.
  • markVisited(nodeA); // Output: Processing: Node A: nodeA is not in visitedNodes, so it's processed and added.
  • markVisited(nodeB); // Output: Processing: Node B: nodeB also gets added and processed.
  • markVisited(nodeA); // No output: nodeA is already in the WeakSet, so nothing happens, it skips processing.

WeakMap in JavaScript

A WeakMap is similar to a Map, but the keys of a WeakMap must be objects and the values can be anything.

The keys are weakly referenced, that means if the object is no longer used anywhere else, it can be garbage-collected.

WeakMap is not iterable and useful for storing private data tied to objects.

Creating a WeakMap

You can create a WeakMap by using new WeakMap() syntax.

const wm = new WeakMap();
 
console.log(wm); // Output: WeakMap(0)

WeakMap Methods

JavaScript provides the following methods to work with WeakMap.

set(object, value):

The set(object, value) method adds a key-value pair to the WeakMap where key is object.

const wm = new WeakMap();
const user = {};
 
wm.set(user, { role: "admin" });

get(object):

The get(object) method is used to retrieve the value of a key.

wm.get(user); // Output: Object { role: "admin" }

has(object):

The has(object) method is used to check if a key exists in a WeakMap.

wm.has(user); // Output: true

delete(object):

The delete(object) method is used to remove the key-value pair.

wm.delete(user); // true

Limitations of WeakMap

  • Keys must be objects.
  • You can’t loop over a WeakMap.
  • No .forEach(), .keys(), .size, or for...of.

Use Case of WeakMap

WeakMap is useful for storing private data per object.

const privateData = new WeakMap();
 
function createUser(name) {
  const user = {};
  privateData.set(user, { name });
 
  return {
    sayHi() {
      console.log(`Hi, I'm ${privateData.get(user).name}`);
    },
  };
}
 
const u1 = createUser("Shefali");
u1.sayHi(); // Output: Hi, I'm Shefali

Here,

  • You create a WeakMap to hold private data for objects.
  • In the function createUser,
    • const user = {};: a new empty object user is created.
    • You store its name inside the privateData WeakMap using user as the key.
    • privateData now looks like: { user → { name: "Shefali" } }.
    • return {...},
      • The returned object has a sayHi() method that can access the user's name using privateData.get(user).
      • But the user object itself is not exposed, it’s trapped in the closure.
  • const u1 = createUser("Shefali"); create a user named "Shefali" and call the sayHi() method.
  • u1.sayHi(); prints Hi, I'm Shefali to the console.
  • privateData isn't accessible outside the closure and won't prevent garbage collection if u1 is discarded.

Tips

  • Use WeakSet and WeakMap only when working with objects.
  • They’re ideal for cases where you don’t want to manually manage memory.
  • They help implement encapsulation, especially in libraries and frameworks.

Map and Set in JavaScript!


Support my work!