🟨 JavaScript Q41 / 121

What is WeakMap and WeakSet?

AI-Powered Answer ✓ Answered

WeakMap and WeakSet are specialized collection objects in JavaScript that allow you to store objects as keys (for WeakMap) or elements (for WeakSet) without preventing those objects from being garbage-collected if no other references to them exist. This 'weak' referencing is their defining characteristic and primary advantage.

WeakMap

A WeakMap is a collection of key-value pairs where keys must be objects and values can be arbitrary JavaScript types. The 'weak' part means that if there are no other references to an object used as a key in a WeakMap, the JavaScript engine's garbage collector can reclaim that object's memory. When the key is garbage collected, its corresponding value is also removed from the WeakMap.

Key characteristics of WeakMap include: - Keys must be objects (not primitive values). - It holds 'weak' references to its keys, meaning keys don't prevent garbage collection. - It is not enumerable (you cannot iterate over its keys, values, or entries). - It does not have a .size property, preventing accidental strong referencing to keys.

WeakMap Use Case: Private Data

One common use case for WeakMap is to store private data for objects. Since WeakMap keys are objects and are weakly referenced, you can associate data with an object such that if the object itself is garbage collected, its associated 'private' data in the WeakMap is also cleaned up automatically.

WeakMap Methods

  • .set(key, value): Adds a key-value pair.
  • .get(key): Returns the value associated with the key.
  • .has(key): Returns true if a key exists, false otherwise.
  • .delete(key): Removes a key-value pair.

WeakMap Example

javascript
const privateData = new WeakMap();

class MyObject {
  constructor(id, secret) {
    this.id = id;
    privateData.set(this, { secret });
  }

  getSecret() {
    return privateData.get(this).secret;
  }
}

let obj1 = new MyObject(1, 'super-secret-1');
console.log(obj1.getSecret()); // super-secret-1

obj1 = null; // No other references to obj1, so it can be garbage collected
             // and its entry in privateData will also be removed.

WeakSet

A WeakSet is a collection of unique objects. Like WeakMap, it holds 'weak' references to its elements. If an object stored in a WeakSet is no longer referenced anywhere else in the code, it can be garbage collected, and subsequently, it will be removed from the WeakSet.

Key characteristics of WeakSet include: - Elements must be objects (not primitive values). - It holds 'weak' references to its elements, meaning elements don't prevent garbage collection. - It is not enumerable (you cannot iterate over its elements). - It does not have a .size property.

WeakSet Use Case: Tracking Object Presence

A typical use case for WeakSet is to track a group of objects without preventing their garbage collection. For example, you might track all currently active DOM elements, or mark objects that have undergone a specific processing step. If an object is removed from the DOM or becomes otherwise unreachable, it naturally leaves the WeakSet.

WeakSet Methods

  • .add(value): Adds an object to the set.
  • .has(value): Returns true if the object is in the set, false otherwise.
  • .delete(value): Removes an object from the set.

WeakSet Example

javascript
const activeUsers = new WeakSet();

let user1 = { name: 'Alice' };
let user2 = { name: 'Bob' };
let user3 = { name: 'Charlie' };

activeUsers.add(user1);
activeUsers.add(user2);

console.log(activeUsers.has(user1)); // true
console.log(activeUsers.has(user3)); // false

user1 = null; // Alice object can now be garbage collected
              // and will be automatically removed from activeUsers.

setTimeout(() => {
  // After garbage collection (non-deterministic timing),
  // has(user1) would eventually return false.
  // This is hard to demonstrate synchronously.
  console.log('After potential GC, user1 still present?', activeUsers.has(user1));
}, 100);

Key Differences and Similarities

FeatureWeakMapWeakSet
PurposeStore key-value pairs (keys are objects)Store unique objects
Keys/ElementsMust be objects (values can be anything)Must be objects
ReferencingWeakly references keysWeakly references elements
Garbage CollectionKeys don't prevent GC; entry removed if key GC'dElements don't prevent GC; element removed if GC'd
Iteration/EnumerationNot possible (`.keys()`, `for...of` etc. not available)Not possible (`for...of` etc. not available)
Size PropertyNo `.size` propertyNo `.size` property
PrimitivesCannot use primitives as keysCannot use primitives as elements

When to Use Them

  • WeakMap: Ideal for associating data with objects without causing memory leaks. For example, storing private instance data, caching computation results based on object inputs, or attaching metadata to DOM elements that should be cleaned up when the element is removed from the DOM.
  • WeakSet: Useful for marking objects or tracking their presence within a collection without affecting their garbage collection lifecycle. For instance, keeping track of objects that are currently 'active' or have been 'visited' to prevent re-processing.

In essence, both WeakMap and WeakSet are powerful tools for managing memory efficiently in JavaScript applications, especially when dealing with long-lived objects or a large number of temporary objects that need associated data or tracking without creating persistent references.