WeakSet in JavaScript

vaishnavi pandey
Last Updated: May 13, 2022

Introduction

WeakSet is one of the most underrated data structures that is used in JavaScript. There exist many JavaScript developers who don't even know they exist. 

 

More than 70% of JavaScript developers have just used objects in their projects to collect and maintain data. Even though they were released in 2015, the newest collection objects, such as a weak map and weak set, remain significantly underutilised.

 

WeakSets are similar to Sets of Javascript. Both WeakSets and Sets are a type of collection. We can use these collections to store values. 

 

In this blog, we will explain the weak set data structure in JavaScript. It's working and how they differ from the sets. So, let's get started.

WeakSets

In JavaScript, a WeakSet is used to store a collection of objects. It has the same qualities as a set, such as not storing duplicates. Thus the objects must be unique. If we try to add some object twice, the second will not be added. Only the first object will remain there.

 

The main distinction between a WeakSet and a set is that a WeakSet is a collection of objects rather than values of a specific type.

 

Another significant difference between Sets and WeakSets, and arrays are that WeakSets are not iterable. We can add items or remove any existing ones. 

 

We can also check if WeakSet contains a specific item. However, We can't iterate over it with some loop. No size property would tell us how many items are in a particular WeakSet.

 

Let’s take a look at how we can create new WeakSets.

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

 

Frequently Asked Questions

  1. What is a WeakMap?

The WeakMap object is a collection of key/value pairs with weak references to the keys.

 

  1. 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 CodeStudio to practise questions on web development and use the Coding Ninja Self-paced Web development to grasp numerous web development concepts.

 

Happy Learning!

 

Was this article helpful ?
0 upvotes

Comments

No comments yet

Be the first to share what you think