Difficulty: Intermediate
What are WeakMap and WeakSet? How do they differ from Map and Set?
WeakMap and WeakSet hold weak references to their keys/values, meaning the garbage collector can collect the referenced objects even if they still appear in the WeakMap/WeakSet.
Key differences from Map/Set: - Keys (WeakMap) or values (WeakSet) must be objects - Not iterable - no forEach, keys(), values(), or size property - Entries are automatically removed when the referenced object is garbage collected
Use cases: - WeakMap: storing private data or metadata associated with DOM nodes or class instances without preventing GC - WeakSet: tracking objects that have been processed
const _private = new WeakMap();
class Counter {
constructor() {
_private.set(this, { count: 0 });
}
increment() {
_private.get(this).count++;
}
get value() {
return _private.get(this).count;
}
}
const c = new Counter();
c.increment();
c.increment();
console.log(c.value); // 2
console.log(c.count); // undefined - truly private
WeakMap stores private state keyed by the instance. When the instance is garbage collected, the data in the WeakMap is also collected.
function deepClone(obj, seen = new WeakSet()) {
if (typeof obj !== 'object' || obj === null) return obj;
if (seen.has(obj)) throw new Error('Circular reference detected');
seen.add(obj);
const clone = Array.isArray(obj) ? [] : {};
for (const key of Object.keys(obj)) {
clone[key] = deepClone(obj[key], seen);
}
return clone;
}
const a = { x: 1, nested: { y: 2 } };
console.log(deepClone(a));
const circular = { name: 'test' };
circular.self = circular;
try {
deepClone(circular);
} catch (e) {
console.log(e.message);
}
WeakSet tracks seen objects without preventing GC. Using a regular Set would hold strong references and could cause memory leaks.
WeakMap, WeakSet, Garbage Collection, Memory