WeakSet
A set of objects that doesn’t keep them in memory. Used for marking objects, e.g. ones already handled.
- Returns
- A new
WeakSetobject.
Example
#const completed = new WeakSet()
const lesson1 = { title: 'Variables' }
const lesson2 = { title: 'Loops' }
completed.add(lesson1)
console.log(completed.has(lesson1))
console.log(completed.has(lesson2))
console.log(completed.has({ title: 'Variables' }))The third check is for a new object with the same content. The set compares objects by reference, so it doesn’t find it.
Definition and usage
#WeakSet is a set similar to Set, but it stores objects, not strings or numbers: trying to add a string or a number throws a TypeError. The set holds its objects "weakly". Once nothing else in the program references an object, the engine can remove it from memory, and the object simply disappears from the set.
It has only three methods: add(), has(), and delete(). It has no size, clear(), forEach(), or any way to iterate over its elements, because its contents can change at any moment while the garbage collector is running. So all you can ask is whether a specific object is in the set.
A typical use is marking objects without changing them: remembering which DOM elements have already been handled, which objects you’ve visited while walking nested data, or which students have already received a reward. Once an object is no longer needed, its entry disappears along with it, with no risk of a memory leak.
Syntax
#new WeakSet()
new WeakSet(iterable)
weakSet.add(object)
weakSet.has(object)
weakSet.delete(object)Parameters
#iterable
optional
An array or other iterable of objects the set is initially filled with.
More examples
#const seen = new WeakSet()
try {
seen.add('Emma')
} catch (error) {
console.log(error.name)
}
seen.add({ id: 1 })
console.log(seen.size)
console.log(seen)const rewarded = new WeakSet()
function award(student) {
if (rewarded.has(student)) {
return `${student.name} already has the badge`
}
rewarded.add(student)
return `Badge awarded to ${student.name}`
}
const emma = { name: 'Emma' }
console.log(award(emma))
console.log(award(emma))function hasCycle(value, path = new WeakSet()) {
if (typeof value !== 'object' || value === null) return false
if (path.has(value)) return true
path.add(value)
const found = Object.values(value).some((child) => hasCycle(child, path))
path.delete(value)
return found
}
const course = { title: 'JS', modules: [] }
console.log(hasCycle(course))
course.modules.push({ parent: course })
console.log(hasCycle(course))JSON.stringify() throws an error for data with a cycle, and a function like this lets you check for one beforehand. The set only holds objects from the current path, so after a value’s children have been checked, it’s removed again.
Browser support
#Widely available
Works in all modern browsers, phones included. You can use it without worry.
- Chrome
- Edge
- Firefox
- Safari
Good practices
#- Choose
WeakSetwhen you only need the answer to "is this object marked". If you want to attach extra data to the object, useWeakMap. - If you need to know the number of elements or loop over them, choose a regular
Set.WeakSetdeliberately doesn’t allow that. - There’s no way to predict when an unused object will disappear from the set. Don’t base your program’s logic on the timing of garbage collection.
Related entries
#- SetA collection of unique values: each value can appear in the set only once.
- WeakMapA map with objects as keys that doesn’t keep them in memory: the entry disappears along with the unused object.
- MapA collection of key-value pairs where the key can be any value and insertion order is preserved.
- JSON.stringify()Converts a JavaScript value, such as an object or array, into a string in JSON format.
- classDefines a class: a template for creating objects that share the same fields and methods.
Spotted a mistake or missing an example? Write to us.