JavaScript WeakSet Data Structure
A WeakSet is a special kind of Set in JavaScript that allows you to store only objects, and those objects are held weakly, meaning they do not prevent garbage collection.
Key characteristics:
- Object-only: WeakSets can only contain objects (no primitives).
- Weak references: If no other references to an object exist, it can be garbage collected.
- Non-iterable: You can’t loop through a WeakSet or get its size.
- Useful for: Private data storage or tracking object existence without preventing garbage collection.
WeakSet vs Set
Here's a quick comparison:
Feature | Set | WeakSet |
---|---|---|
Stores | Any value | Objects only |
Iterable? | Yes | No |
Garbage Collectable? | No | Yes |
Methods | Many (add, delete, has, clear, etc.) | Limited (add, delete, has) |
Creating a WeakSet
A WeakSet is created using the new WeakSet() constructor. Unlike a regular Set, a WeakSet can only contain objects—not primitive values like numbers or strings.
1. Creating an Empty WeakSet
You can create an empty WeakSet and add object references later using the add() method.
const ws = new WeakSet();
const user = { name: 'Tom' };
ws.add(user);
console.log(ws.has(user)); // Output: true
const ws = new WeakSet();
const user = { name: 'Tom' };
ws.add(user);
console.log(ws.has(user)); // Output: true
2. Initializing WeakSet with Objects
You can also create a WeakSet from an array or other iterable containing objects.
const obj1 = {};
const obj2 = {};
const obj3 = {};
const ws = new WeakSet([obj1, obj2, obj3]);
console.log(ws.has(obj2)); // Output: true
const obj1 = {};
const obj2 = {};
const obj3 = {};
const ws = new WeakSet([obj1, obj2, obj3]);
console.log(ws.has(obj2)); // Output: true
3. Invalid Values Cause Errors
If you try to add a non-object value to a WeakSet, it will throw a TypeError.
const ws = new WeakSet();
ws.add(123); // ❌ TypeError: Invalid value used in weak set
const ws = new WeakSet();
ws.add(123); // ❌ TypeError: Invalid value used in weak set
Only object references are allowed. This ensures the "weak" referencing behavior works properly for garbage collection.
Accessing WeakSet Elements
Accessing elements in a WeakSet is different from a regular Set. Since WeakSet is not iterable, you can’t use loops, forEach(), or access elements by index.
The only way to check if an object exists in a WeakSet is by using the has() method.
1. Checking for an Object with has()
The has() method checks whether a specific object is present in the WeakSet.
const user1 = { name: 'Tom' };
const user2 = { name: 'Bob' };
const ws = new WeakSet([user1]);
console.log(ws.has(user1)); // Output: true
console.log(ws.has(user2)); // Output: false
const user1 = { name: 'Tom' };
const user2 = { name: 'Bob' };
const ws = new WeakSet([user1]);
console.log(ws.has(user1)); // Output: true
console.log(ws.has(user2)); // Output: false
2. Why WeakSets Aren’t Iterable
WeakSets are intentionally not iterable to support garbage collection. If JavaScript allowed iteration, it would have to prevent items from being collected, defeating the purpose of weak references.
As a result, methods like for...of, forEach(), or size don’t work on WeakSets:
const ws = new WeakSet([{ id: 1 }]);
// ❌ These will all throw errors:
for (const item of ws) {} // TypeError
ws.forEach(() => {}); // TypeError
console.log(ws.size); // undefined
const ws = new WeakSet([{ id: 1 }]);
// ❌ These will all throw errors:
for (const item of ws) {} // TypeError
ws.forEach(() => {}); // TypeError
console.log(ws.size); // undefined
Because of this limitation, WeakSet is primarily used in scenarios where you just need to track the presence of an object privately or temporarily.
Modifying WeakSet Elements
While WeakSet does not support direct access to its elements, you can modify its contents using three primary methods: add(), delete(), and indirectly through has().
1. Adding Elements with add()
The add() method inserts a new object into the WeakSet. If the object is already in the set, it will not be added again.
const ws = new WeakSet();
const item = { id: 1 };
ws.add(item);
console.log(ws.has(item)); // Output: true
const ws = new WeakSet();
const item = { id: 1 };
ws.add(item);
console.log(ws.has(item)); // Output: true
2. Deleting Elements with delete()
Use delete() to remove an object from the WeakSet. It returns true if the object was found and removed, or false if it wasn’t in the set.
const ws = new WeakSet();
const obj = { name: 'Test' };
ws.add(obj);
ws.delete(obj); // true
console.log(ws.has(obj)); // false
const ws = new WeakSet();
const obj = { name: 'Test' };
ws.add(obj);
ws.delete(obj); // true
console.log(ws.has(obj)); // false
3. Replacing an Object
Since WeakSets store only object references and don’t support indexing or iteration, replacing an object involves removing the old reference and adding a new one.
const ws = new WeakSet();
const oldObj = { key: 'old' };
const newObj = { key: 'new' };
ws.add(oldObj);
// Replace oldObj with newObj
if (ws.has(oldObj)) {
ws.delete(oldObj);
ws.add(newObj);
}
const ws = new WeakSet();
const oldObj = { key: 'old' };
const newObj = { key: 'new' };
ws.add(oldObj);
// Replace oldObj with newObj
if (ws.has(oldObj)) {
ws.delete(oldObj);
ws.add(newObj);
}
Remember, WeakSets do not update objects. You must manage object references manually if changes are needed.
WeakSet Methods
WeakSets have only three main methods:
- add(value): Adds an object to the WeakSet.
- has(value): Returns true if the object exists in the WeakSet.
- delete(value): Removes an object from the WeakSet.
const ws = new WeakSet();
const user = { name: 'Tom' };
ws.add(user);
console.log(ws.has(user)); // true
ws.delete(user);
console.log(ws.has(user)); // false
const ws = new WeakSet();
const user = { name: 'Tom' };
ws.add(user);
console.log(ws.has(user)); // true
ws.delete(user);
console.log(ws.has(user)); // false
Frequently Asked Questions
What is a WeakSet in JavaScript?
What is a WeakSet in JavaScript?
A WeakSet is a special collection of objects held weakly. It allows objects to be garbage-collected if there are no other references to them.
How do you create a WeakSet?
How do you create a WeakSet?
You can create a WeakSet using new WeakSet(), and optionally initialize it with an array of objects: new WeakSet([obj1, obj2]).
What types of values can a WeakSet store?
What types of values can a WeakSet store?
WeakSet can only store **objects**. You cannot store primitive values like numbers, strings, or booleans.
Can you iterate over a WeakSet?
Can you iterate over a WeakSet?
No, WeakSet is not iterable. You cannot use loops like for...of or methods like forEach() to view its contents.
How do you check or remove items in a WeakSet?
How do you check or remove items in a WeakSet?
Use has(object) to check if it’s in the set, and delete(object) to remove it. These return true or false.
What's Next?
Next: Types of Arrays – explore the various ways arrays can be used and structured in JavaScript.