JavaScript WeakSet
In JavaScript, a WeakSet is a specialized collection introduced in ES6, similar to Set
but with important differences. It is designed to store weak references to objects only, allowing garbage collection when no other references to the objects exist.
- A WeakSet stores unique object references (no primitives like strings or numbers).
- Weak references: Objects in a WeakSet can be garbage-collected if there are no other references.
- Non-iterable: You cannot loop through a WeakSet or inspect its contents directly.
Key Features:
Feature | WeakSet |
---|---|
Stores | Objects only |
Duplicates | Not allowed |
Iterable | No |
Size property | No .size |
Methods | .add() , .has() , .delete() |
Garbage collection support | Yes, automatic |
Example:
const weakSet = new WeakSet();
const obj = {};
weakSet.add(obj);
console.log(weakSet.has(obj)); // true
// obj removed from memory when no references exist
WeakSet Methods
.add(value)
– Adds an object (ignores duplicates, non-objects throw TypeError)
const weakSet = new WeakSet();
const obj1 = {};
weakSet.add(obj1);
.has(value)
– Checks if an object exists in the WeakSet
console.log(weakSet.has(obj1)); // true
console.log(weakSet.has({})); // false (different reference)
.delete(value)
– Removes an object from the WeakSet
weakSet.delete(obj1);
console.log(weakSet.has(obj1)); // false
WeakSet vs Set
Feature | Set | WeakSet |
---|---|---|
Stores | Any value (primitives & objects) | Objects only |
Reference type | Strong | Weak (allows GC) |
Iterable | Yes | No |
Size | .size available | No .size |
Methods | .keys() , .values() , .entries() | .add() , .has() , .delete() |
Use case | General-purpose collections | Temporary object tracking |
Use Cases
Object Tracking – Track objects without preventing garbage collection.
const weakSet = new WeakSet();
const div = document.createElement("div");
weakSet.add(div);
- Prevent Memory Leaks – Store metadata for objects without keeping them alive unnecessarily.
- Marking Instances – Flag objects or class instances as "processed" without exposing them.
- Private Data in Classes – Keep references private inside a class.
Practical Example with Classes
class Car {
#year; // private
constructor(name, year) {
this.name = name;
this.#year = year;
}
getYear() { return this.#year; }
}
class CarRegistry {
#trackedCars = new WeakSet();
addCar(car) {
if (car instanceof Car) this.#trackedCars.add(car);
}
isTracked(car) { return this.#trackedCars.has(car); }
}
const registry = new CarRegistry();
let car1 = new Car("Ford", 2014);
const car2 = new Car("Audi", 2019);
registry.addCar(car1);
registry.addCar(car2);
console.log(registry.isTracked(car1)); // true
car1 = null; // garbage-collected automatically
Limitations
- Non-iterable – Cannot loop or check size.
- Objects only – Primitives throw TypeError.
- No serialization – Cannot use JSON.stringify.
- GC Timing – Cannot predict exactly when objects are removed.
Copying WeakSet
- Shallow copy: Not directly possible, must manually recreate by adding objects.
- Deep copy: Clone objects individually using
structuredClone()
but not the WeakSet itself.
const weakSet = new WeakSet();
const obj = { id: 1 };
weakSet.add(obj);
const clonedObj = structuredClone(obj);
weakSet.add(clonedObj);