Creating a new WeakSet
When you want to create new WeakSets, you have to use WeakSet() constructor. This will create a new WeakSet we can then use to store values.
There are two ways in which we can use the WeakSet() constructor.
- First, we can use it to create an empty WeakSet and add to its values later.
- Then, there is another thing we can do. We can pass an iterable with values as a parameter to the constructor when you use it to create a new WeakSet. When we hear the word, “iterable” imagine some collection of values are there. In this case, the array is iterable. So, we can pass in an array with objects.
Syntax:
const myWeakSet = new WeakSet()
const myWeakSet = new WeakSet([myObj1, myObj1])
Methods of WeakSet
We already have talked a bit about what WeakSets allow us to do. We can add items to WeakSets, and we can remove them also. We can also check if some WeakSet contains a specific item. There are specific methods to perform each of these tasks. Let's take a look at them.
Adding a new Object
When we want to add objects to WeakSets, we can do two things.
- First, we can pass those objects into the WeakSet() constructor when creating a new WeakSet.
- Second, we can add objects later with the help of add() method. This method can accept one parameter, the object we want to store.
This is something we should remember. It can accept only one object, not more. If we try to pass in multiple objects, only the first will be added to the WeakSet. The rest time, it will be ignored. So, if we want to add multiple objects, we can use multiple add() methods for each.
Code Snippet:
var demoset = new WeakSet();
demoset.add(window); // add the window object to the WeakSet
demoset.has(window); // true
// Weakset only takes objects as arguments
demoset.add(1);
Output:
"TypeError: Invalid value used in weak set" in Chrome
Removing Objects
Removing objects from WeakSets is simple. When we want to remove some object, we use the method delete().
This method accepts one parameter, the name of the object we want to remove. It also works with one object at a time. So, if we want to remove multiple objects, we have to use multiple delete() methods, one for each object.
This method returns a boolean. It would return true if the object were successfully removed. If the object is not stored in WeakSet, it will return false.
Code Snippet:
var demoset = new WeakSet();
var obj = {};
demoset.add(window);
demoset.delete(obj); // Returns false. No obj found to be deleted.
demoset.delete(window); // Returns true. Successfully removed.
demoset.has(window); // Returns false. The window is no longer present in the WeakSet.
Checking if the object exists
Since the WeakSets are not iterable, and there is no size property in them. This made it hard to know if the specific object does or doesn’t exist in a WeakSet.
There is a method we can use to find this out. The name of the method is has(). It is similar to delete() and add() and accepts one parameter.
This parameter can be the name of an object we want to check for. When we use this method, it also returns a boolean, just like delete(). It returns either true if an object is present in a WeakSet or false if it is not present.
Code Snippet:
var ws = new WeakSet();
var obj = {};
ws.add(window);
mySet.has(window); // returns true
mySet.has(obj); // returns false
Decoding the has() Function
I hope we understand why iterable WeakSets and size property doesn’t make sense. What about the has() method? The has() is a different story. Think about how we use this method and how it works. When we use it, we pass in the name of the object we want to check for.
The variable name is a reference. When we pass it in, we don’t pass in the object itself. Instead, we pass in that reference. Reference is the memory address of that variable. It is a pointer(address) to the memory location where the variable is to be stored.
Let us move Back to garbage collection. Garbage collection collects objects only when the references to those objects are not there. Otherwise, it will leave them alone. When we use the has() method, and we pass in reference to some object, it means that at least one reference is there.
This means that the object was not garbage collected. It still exists. So, if we use the has() method, we will get reliable information. This is the reason why has() method does make sense here, while iteration and size property don’t. The has() requires a reference, existing object. The iteration and size property don’t.
Use Cases for WeakSets
When we want to store some values, we are unsure about the choice? One scenario where WeakSets is useful is tracking available objects. We can store references to those objects in an array or a Map. This would prevent the garbage collection from collecting any of those objects if all other references to them were gone. These objects will remain in memory and could potentially lead to a memory leak. We Use WeakSets to store those objects, and we no longer have this problem.
A straightforward example is a login system. We could keep track of users (objects) that are online by adding them to a WeakSet. When any of those users leave, We remove the appropriate object. Later, We can use the has() method to check if a specific user is still online, the appropriate object is present, or not.
// Create three users that are logged into a system
let user1 = { username: 'Aiesha' }
let user2 = { username: 'Shruti' }
let user3 = { username: 'Juhi' }
// Create new WeakSet
const loggedUsers = new WeakSet()
// Add "user1" to "loggedUsers"
loggedUsers.add(user1)
// Add "user2" to "loggedUsers"
loggedUsers.add(user2)
// Add "user3" to "loggedUsers"
loggedUsers.add(user3)
//let us Check if all users are present
loggedUsers.has(user1)
Output:
true
loggedUsers.has(user2)
Output:
true
loggedUsers.has(user3)
Output:
true
// When "user2" and "user3" log out
user2 = null
user3 = null
// Let us Check if all users are still logged in
loggedUsers.has(user1)
Output:
true
loggedUsers.has(user2)
Output:
false
loggedUsers.has(user3)
Output:
false
You can practice by yourself with the help of an online javascript editor.
Frequently Asked Questions
- What is a WeakMap?
The WeakMap object is a collection of key/value pairs with weak references to the keys.
- What is WeakSet?
WeakSet is a collection of objects only, and they cannot contain arbitrary values of any type, as sets can have arbitrary values.
Key takeaways
In this blog, we learned that WeakSets are one of those lesser-known features of JavaScript. Indeed, they are not the best choice for storing data. However, there are jobs WeakMaps are a better fit for.
I hope you learned what WeakSets are, how they function, how they differ from Sets and other collections, and how to utilise them from this article.
You can use Coding Ninjas Studio to practise questions on web development and use the Coding Ninja Self-paced Web development to grasp numerous web development concepts.
Happy Learning!