If you look at both of these examples of WeakRef
polyfills, they both use WeakMap
.
But I don't see how that can work. A WeakMap
doesn't hold weak references to its values, but to its keys. And both those polyfills use this
as the key. Which means if I say let weakRef = new WeakRef(targetObject)
, then targetObject
will never get garbage collected unless I throw away weakRef
. Which negates the entire purpose of WeakRef
, doesn't it?
In my limited experimentation my theory seems to be correct. Check out this jsfiddle.
Furthermore, does anyone know a WeakRef
polyfill that does work?
It seems this is a result of misunderstanding on part of the polyfill authors, please consider writing a bug report.
These approaches indeed keep a strong reference to the object, an implementation which is technically conforming, because the program can't argue that a garbage collector is broken just because it was never observed removing an object. However, to achieve this feat would have been much easier: just store the object in a property and don't bother with a
WeakMap
at all.I think some people naïvely expect that a
WeakMap
has weak references to the values, as you observed. I also used to have such misconception before reading the docs carefully. Nevertheless, this would not explain whyWeakMap
has been in the spec since 2015 whileWeakRef
hasn't made it past the proposal stage yet, for over 3 years. Such naïve collection would be like aMap
ofWeakRefs
, so why would the language not also expose a single one?Truth is, it is impossible to mimic
WeakRef
withWeakMap
and careful design has been taken to make it so (primarily, that it is not enumerable). Why? While it is perfectly possible to implement this behaviour reliably, the sentiment in the design group is towards determinism and predictability. This short paragraph summarizes it nicely, with reasoning and an example considered a wrong design past decision. The following two sentences directly preclude anything like aWeakRef
:With this in mind, in an implementation following the W3C TAG guidelines, not only
WeakMap
can't be used, but not even any other approach (which should answer your last question in the comments), except possibly using an ugly and unreliable loophole like that mentioned in the example, for narrowly specific cases. Unless the opinion of the committee changes radically, theWeakRef
proposal may never really be standardized. Let's hope that a carefully worded note of caution, as included in the current version, and an appeal to excess memory usage and other interesting and well-founded use cases, will eventually allow such exception.