javascriptweakmap

How can a weak map be implemented in ES5?


There is another question that asks the same, but I cannot grok the accepted answer.

The library in question appears to use Object.defineProperty to add a reference to the object to be stored (albeit indirectly via another object).

But... surely that would then mean the object cannot be garbage collected because of this link?

What am I missing?

Is it really possible to create an object and store it somewhere without maintaining a reference noticeable by the garbage collector? (Prior to ES2015)

The accepted answer:

It took me a while to grok the code, but then it hit me: the key itself is used to store a reference to the value.

For example, several layers into set it does

defProp(obj, globalID, { value: store }); where defProp has been defined to be Object.defineProperty, obj is the key, globalID is a guid and store is a storage object that contains the value.

Then down in get it looks up the value with

obj[globalID];

This is very clever. The WeakMap doesn't actually contain a reference to anything (weak or otherwise)-- it just sets up a policy of where to secretly store the value. The use of Object.defineProperty means that you won't accidentally discover the value storage-- you have to know the magic guid to look it up.

Since the key directly refers to the value (and the WeakMap doesn't refer to it), when all references to the key are gone, it gets GCed like normal.

The library in question.


Solution

  • surely that would then mean the object cannot be garbage collected because of this link?

    Yes.

    What am I missing?

    Nothing. Maybe that this is exactly the desired behaviour.

    As the answer explains, "the WeakMap doesn't actually contain a reference to anything (weak or otherwise)" and "when all references to the key are gone, it gets GCed like normal."