JavaScript Notes
Master JavaScript WeakSet with real-world examples, garbage collection internals, comparison with Set, methods, use cases, and interview questions. Learn weak references in JavaScript.
Introduction — What is WeakSet?
A WeakSet is a built-in JavaScript collection that stores only objects (and Symbols) as unique values, while holding weak references to them. Unlike a regular Set, a WeakSet does not prevent its stored objects from being garbage collected.
What are Weak References?
In JavaScript, a strong reference keeps an object alive in memory — the garbage collector cannot remove it. A weak reference allows the garbage collector to reclaim the object if no other strong references exist.
This makes WeakSet ideal for tagging objects without preventing their cleanup.
WeakSet Methods
WeakSet has only three methods — intentionally minimal because weak references make enumeration unreliable.
1. weakSet.add(value)
Adds an object to the WeakSet. Returns the WeakSet itself (for chaining).
const ws = new WeakSet();
const obj1 = { name: "Alice" };
const obj2 = { name: "Bob" };
ws.add(obj1).add(obj2); // Chaining works
console.log(ws.has(obj1));
console.log(ws.has(obj2));true true
2. weakSet.has(value)
Returns true if the object exists in the WeakSet, false otherwise.
const ws = new WeakSet();
const user = { id: 1 };
const admin = { id: 2 };
ws.add(user);
console.log(ws.has(user));
console.log(ws.has(admin));
console.log(ws.has({ id: 1 })); // Different object reference!true false false
3. weakSet.delete(value)
Removes an object from the WeakSet. Returns true if successfully removed, false if not found.
const ws = new WeakSet();
const item = { type: "product" };
ws.add(item);
console.log(ws.has(item));
const deleted = ws.delete(item);
console.log(deleted);
console.log(ws.has(item));
const deletedAgain = ws.delete(item);
console.log(deletedAgain);true true false false
What WeakSet Does NOT Have
- ❌
.size— Cannot know how many items exist - ❌
.forEach()— Cannot iterate - ❌
.keys()/.values()/.entries()— No iterators - ❌
.clear()— Cannot bulk-remove (GC handles cleanup) - ❌
for...of— Not iterable
How Garbage Collection Works with WeakSet
Important: You cannot observe GC happening in real-time. Garbage collection is non-deterministic — the engine decides when to run it.
Code Examples
Example 1: Basic Usage
const weakSet = new WeakSet();
const person = { name: "Rahul" };
const car = { brand: "Toyota" };
weakSet.add(person);
weakSet.add(car);
console.log(weakSet.has(person));
console.log(weakSet.has(car));
console.log(weakSet.has({ name: "Rahul" })); // New object!
weakSet.delete(car);
console.log(weakSet.has(car));true true false false
A new object { name: "Rahul" } is a different reference — WeakSet uses reference equality, not structural equality.
Example 2: Tracking Visited Objects
const visited = new WeakSet();
function processNode(node) {
if (visited.has(node)) {
console.log(`Already visited: ${node.id}`);
return;
}
visited.add(node);
console.log(`Processing: ${node.id}`);
}
const nodeA = { id: "A", data: "Hello" };
const nodeB = { id: "B", data: "World" };
processNode(nodeA);
processNode(nodeB);
processNode(nodeA); // Already visited
processNode(nodeB); // Already visitedProcessing: A Processing: B Already visited: A Already visited: B
When nodeA or nodeB go out of scope elsewhere, WeakSet will not prevent their garbage collection.
Example 3: Preventing Duplicate Processing
const processed = new WeakSet();
function sendNotification(user) {
if (processed.has(user)) {
console.log(`Skipped: ${user.email} (already notified)`);
return false;
}
processed.add(user);
console.log(`Sent notification to: ${user.email}`);
return true;
}
const user1 = { email: "dev@wohotech.com" };
const user2 = { email: "admin@wohotech.com" };
console.log(sendNotification(user1));
console.log(sendNotification(user2));
console.log(sendNotification(user1)); // Duplicate
console.log(sendNotification(user1)); // Duplicate againSent notification to: dev@wohotech.com true Sent notification to: admin@wohotech.com true Skipped: dev@wohotech.com (already notified) false Skipped: dev@wohotech.com (already notified) false
Example 4: Circular Reference Detection
Circular reference detected! Returning null. Priya [10, 20] null
Without WeakSet, this would cause infinite recursion and a stack overflow.
Example 5: Private Data Pattern (Branding)
const verified = new WeakSet();
class SecureToken {
constructor(payload) {
this.payload = payload;
verified.add(this); // Brand this instance
}
static isVerified(token) {
return verified.has(token);
}
}
const token1 = new SecureToken({ userId: 42 });
const fakeToken = { payload: { userId: 42 } }; // Imposter!
console.log(SecureToken.isVerified(token1));
console.log(SecureToken.isVerified(fakeToken));
console.log(token1.payload.userId === fakeToken.payload.userId);true false true
Even though fakeToken has identical data, the WeakSet knows it was never created by the constructor. This is called branding.
Example 6: DOM Element Tracking
// Simulating DOM elements as objects
const activeElements = new WeakSet();
function activate(element) {
activeElements.add(element);
console.log(`Activated: ${element.tagName}#${element.id}`);
}
function deactivate(element) {
activeElements.delete(element);
console.log(`Deactivated: ${element.tagName}#${element.id}`);
}
function isActive(element) {
return activeElements.has(element);
}
const btn = { tagName: "BUTTON", id: "submit" };
const input = { tagName: "INPUT", id: "email" };
activate(btn);
activate(input);
console.log("btn active:", isActive(btn));
console.log("input active:", isActive(input));
deactivate(btn);
console.log("btn active after deactivate:", isActive(btn));Activated: BUTTON#submit Activated: INPUT#email btn active: true input active: true Deactivated: BUTTON#submit btn active after deactivate: false
In a real app, when DOM elements are removed from the page, WeakSet entries are garbage collected automatically — no need for manual cleanup event listeners.
Example 7: Constructor with Iterable
true true true false
Real-World Use Cases
- Tracking visited nodes in graph/tree traversal algorithms
- Preventing duplicate event handling for DOM elements
- Branding pattern — verifying objects were created by your constructor
- Circular reference detection in serialization (JSON.stringify alternatives)
- Caching metadata about objects without preventing their cleanup
- Marking disabled UI components without creating memory leaks
- Framework internals — React, Vue, and Angular use WeakSets for component tracking
Common Mistakes
Mistake 1: Adding Primitive Values
const ws = new WeakSet();
try {
ws.add(42);
} catch (e) {
console.log(e.message);
}
try {
ws.add("hello");
} catch (e) {
console.log(e.message);
}
try {
ws.add(true);
} catch (e) {
console.log(e.message);
}Invalid value used in weak set Invalid value used in weak set Invalid value used in weak set
Fix: Only objects and registered Symbols can be added.
Mistake 2: Trying to Iterate
const ws = new WeakSet();
ws.add({ x: 1 });
ws.add({ x: 2 });
// All of these will fail:
console.log("size" in ws && ws.size !== undefined);
try {
for (const item of ws) {
console.log(item);
}
} catch (e) {
console.log("Cannot iterate:", e.message);
}false Cannot iterate: ws is not iterable
Fix: WeakSet is not iterable by design — use Set if you need enumeration.
Mistake 3: Expecting Reference Equality to Work Like Value Equality
const ws = new WeakSet();
ws.add({ id: 1 });
// This is a DIFFERENT object with the same structure
console.log(ws.has({ id: 1 }));false
Fix: Store the reference in a variable and use that variable for both add and has.
Mistake 4: Using WeakSet as a Counter
undefined undefined
Fix: If you need to count elements, use a regular Set or maintain a separate counter.
Mistake 5: Adding null or undefined
const ws = new WeakSet();
try {
ws.add(null);
} catch (e) {
console.log("null:", e.message);
}
try {
ws.add(undefined);
} catch (e) {
console.log("undefined:", e.message);
}null: Invalid value used in weak set undefined: Invalid value used in weak set
Fix: Always validate that values are actual objects before adding to a WeakSet.
Key Takeaways
- WeakSet stores only objects (and Symbols) — primitives throw a TypeError.
- References are weak — the garbage collector can reclaim objects if no other strong references exist.
- Not iterable — you cannot loop over WeakSet entries, get size, or enumerate keys.
- Only three methods —
add(),has(), anddelete(). That's it. - Reference equality — two objects with identical properties are different unless they share the same reference.
- Memory-safe by design — impossible to create memory leaks through forgotten entries.
- Use for tagging/branding — mark objects as "seen", "processed", "verified" without preventing cleanup.
- Constructor accepts iterables —
new WeakSet([obj1, obj2])works for initial population. - Non-deterministic cleanup — you cannot predict when or observe that GC has removed entries.
- Prefer WeakSet over Set when you only need
has()checks on objects that may become unreachable.
Interview Questions
Q1: Why can't you iterate over a WeakSet?
Answer: WeakSet entries can be garbage collected at any time. If iteration were allowed, the results would be non-deterministic — different on each call depending on when GC runs. JavaScript intentionally prevents this unpredictability by making WeakSet non-iterable.
Q2: What happens if you add the same object twice to a WeakSet?
const ws = new WeakSet();
const obj = { key: "value" };
ws.add(obj);
ws.add(obj); // Adding again
console.log(ws.has(obj));
ws.delete(obj);
console.log(ws.has(obj));true false
Answer: Like Set, WeakSet stores unique values. Adding the same reference again is a no-op — it doesn't throw an error or create duplicates.
Q3: Can you use WeakSet to detect if an object was created by a specific class?
Answer: Yes! This is called the branding pattern. Add this to a WeakSet inside the constructor, then check with has() to verify instances. External code cannot fake membership because they cannot access the WeakSet (if it's in a closure or module scope).
Q4: What's the difference between WeakSet and WeakRef?
Answer: WeakSet is a collection — it holds multiple objects with weak references for membership testing. WeakRef wraps a single object with a weak reference, allowing you to access the object (if alive) via .deref(). WeakSet cannot retrieve stored objects; it can only test presence.
Q5: When should you NOT use WeakSet?
Answer: Do not use WeakSet when you need to:
- Iterate over stored values
- Know the count of elements
- Store primitive values (strings, numbers, booleans)
- Retrieve stored objects later (WeakSet only tests presence)
- Share data between contexts that need enumeration
FAQ
Is WeakSet supported in all browsers?
Yes. WeakSet has been supported since ES2015 (ES6) in all modern browsers — Chrome 36+, Firefox 34+, Safari 9+, Edge 12+, and Node.js 0.12+. It is safe to use in production without polyfills.
Can I store Symbols in a WeakSet?
Since ES2023, registered Symbols (created with Symbol()) can be stored in WeakSets. However, Symbol.for() Symbols (globally registered) cannot be stored because they are never garbage collected.
Does WeakSet have a .clear() method?
No. The .clear() method was removed from the specification. Since entries are automatically cleaned up by garbage collection, manual clearing was deemed unnecessary and could create security concerns.
How do I know when an object is removed from WeakSet by GC?
You cannot directly observe this. If you need cleanup notifications, use FinalizationRegistry alongside WeakSet. The registry's callback fires when the object is collected, but timing is still non-deterministic.
Can WeakSet cause memory leaks?
No — that's its primary advantage. Since all references are weak, objects in a WeakSet are eligible for garbage collection when no other code holds a strong reference. This makes WeakSet inherently leak-proof for object-tagging scenarios.
Exam Focus
Revise definitions, diagrams, examples, and short-answer points for JavaScript WeakSet — Complete Guide with Examples 2026.
Interview Use
Prepare one clear explanation, one practical example, and one common mistake for this JavaScript Master Course topic.
Search Terms
javascript-complete-guide, javascript master course, javascript, complete, guide, data, structures, weakset
Related JavaScript Master Course Topics