Menu Home

WeakSet

Hi everyone, and welcome to another exciting edition of Boring JavaScript! Today, we weakly tackle the WeakSet object.

Don’t like to read? Then watch the video.

I Thought I Could Lift It

If you are familiar with Set(), then WeakSet() will look pretty much exactly the same. Let’s go through the basics.

With any set (WeakSet() and Set()), you can add, remove, and query the set to see if a specific object is contained within the collection. For example:

const cat = { name: "Fluffy", weight: 2.6 };
const dog = { name: "Rover", weight: 15.4 };
const lizard = { name: "Larry", weight: .2 };

const myZoo = new WeakMap();
myZoo.add(cat);
myZoo.add(dog);

console.log(myZoo.has(cat));    // outputs true
console.log(myZoo.has(dog));    // outputs true
console.log(myZoo.has(lizard));   // outputs false

myZoo.delete(dog);

console.log(myZoo.has(dog));     // outputs false

As with any set, you simple use ‘add’ to add any object to the list, ‘delete’ to remove an object, and ‘has’ to see if the object is inside the set.

Yes, just the basic operations. So what makes it different from Set()? One difference is that you can only store objects within the WeakSet(), where as anything can be stored within the Set().

But there is a HUGE difference we need to cover.

I Can’t Hold On Much Longer

The reason this is called a WeakSet() is that the objects added to the WeakSet() are weakly held. That is, once any reference to the object is no longer needed by JavaScript, the entry in the WeakSet() is automatically removed by the garbage collection system. This doesn’t happen with a normal Set().

And that’s very important. If you add an object to a Set(), and that object isn’t used any more, it will never get garbage collected. The result? Memory Leaks!

This problem is solved when using WeakSet(). If the object that is added to the WeakSet() is no longer needed by JavaScript, it will get garbage collected and the item is removed.

So What Are The Use Cases?

Once great use for WeakSets() is to protect the methods of a class from being executed against objects outside of the instance of the class. For example, take the following code snippet:

const myAnimal = new Animal();
myAnimal.speak();

const rock = { name: 'rock' };
Animal.prototype.speak.call(rock);

Line 2 uses the speak() method against an instance of the object. But line 5 uses the call() method (available to all functions by default) to assign another ‘this’ to the speak() method. Result? speak() can be used against another object, and who knows what could happen to it.

But now let’s use a WeakSet() and prevent that. Let’s build our class like this:

const allAnimals = new WeakSet();

class Animal {
	constructor() {
		allAnimals.add(this);
		this.sound = "Moo";
	}

	speak() {
		if (!allAnimals.has(this)) {
			throw new TypeError('You can only get an official animal to speak!');
		} else {
			console.log(`The animal says "${this.sound}".`)
		}
	}
}

Notice first the constructor. We are adding ‘this’ to the WeakSet “allAnimals” (‘this’ is an object, remember). Now look at speak(). The first thing we check to see is if ‘this’ is contained within the WeakSet. If it is, that means we are calling speak() against an instance of the class. And since only instances of this class are added to the WeakSet(), any attempt to call speak() outside of the class will now throw an exception.

Cool, uh?

The Video

Here is a video we made on the subject:

Shameless Plug

Check us out everywhere!

Check out all our videos at: https://www.boringjavascript.com

Check out everything at: https://www.thevirtuoid.com

Facebook: https://www.facebook.com/TheVirtuoid

Twitter: https://twitter.com/TheVirtuoid

YouTube: https://www.youtube.com/channel/UCKZ7CV6fI7xlh7zIE9TWqgw

Categories: Boring JavaScript Javascript

Tagged as:

thevirtuoid

Web Tinkerer. No, not like Tinkerbell.

Creator of the game Virtuoid. Boring JavaScript. Visit us at thevirtuoid.com

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: