There are a lot of information about WeakMap, which can be referred to:

ES6 Tutorial

ES6 series WeakMap

This article focuses on how to understand the concept of “weak reference”

Weak references vs strong references

We understand the difference between weak and strong references by comparing WeakMap and Map:

var m = new Map(a)function Foo() {
  this.arr = new Array(5 * 1024 * 1024)}var f = new Foo()
m.set(f, 'data')
Copy the code
var wm = new WeakMap(a)function Foo() {
  this.arr = new Array(5 * 1024 * 1024)}var f = new Foo()
wm.set(f, 'data')
Copy the code

The memory model for the above two pieces of code can be expressed roughly as follows:

In Figure 1, because Foo object is referenced by both F and Map object, its reference count is 2. In Figure 2, because it is referenced by WeakMap object, it is a weak reference and is not included in the reference count, so its value is 1.

Weak references and garbage collection

If we break f’s reference to Foo, Foo will be collected by the garbage collector because its reference count is zero.

var wm = new WeakMap(a)function Foo() {
  this.arr = new Array(5 * 1024 * 1024)}var f = new Foo()
wm.set(f, 'data')
f = null
Copy the code

To verify that WeakMap works, we usually try to print wm.get(f), which is undefined:

var wm = new WeakMap(a)function Foo() {
  this.arr = new Array(5 * 1024 * 1024)}var f = new Foo()
wm.set(f, 'data')
f = null
console.log(wm.get(f)) // undefined
Copy the code

The results met expectations, very good!

It would be naive if it ended there. As in the above code, we changed WeakMap to Map, and found that the result was undefined.

Why is that? When wm. Get (f) is executed, wm. Get (null) is executed. WeakMap or Map is always undefined. In fact, when F disconnects from Foo, the only channel to Foo is cut off. This creates a paradoxical situation: to make an object recyclable, all references must be broken; WeakMap requires a reference to the object to perform get.

So how do you verify that WeakMap works?

How do I verify that WeakMap works

How to validate in NodeJS is already covered in this article, but here’s another way to validate in browsers:

In Chrome, we can use the Developer Tools memory panel to debug Map. Let’s start by debugging Map:

  1. Execute the following code on the console
var m = new Map(a)function Foo() {
  this.arr = new Array(5 * 1024 * 1024)}var f = new Foo()
m.set(f, 'data')
f = null
Copy the code
  1. Click on thememoryPanel in the small dot, record the current memory snapshot, searchFoo, found the existence of a visibleFooThe object was not collected.

Then try WeakMap again:

  1. Execute the following code on the console
var wm = new WeakMap(a)function Foo() {
  this.arr = new Array(5 * 1024 * 1024)}var f = new Foo()
wm.set(f, 'data')
f = null
Copy the code
  1. Click on thememoryPanel in the small dot, record the current memory snapshot, searchFoo, it does not exist, so it has been reclaimed.

conclusion

I always think WeakMap should be a very simple thing, but a little deeper still dig out a lot of knowledge points, I really dare not “despise” any knowledge in the future.