Is it possible to create a "weak reference" in JavaScript?
Update: Since July, 2020 some implementations (Chrome, Edge, Firefox and Node.js) has had support for WeakRef
s as defined in the WeakRefs proposal, which is a "Stage 3 Draft" as of December 16, 2020.
There is no language support for weakrefs in JavaScript. You can roll your own using manual reference counting, but not especially smoothly. You can't make a proxy wrapper object, because in JavaScript objects never know when they're about to be garbage-collected.
So your ‘weak reference’ becomes a key (eg. integer) in a simple lookup, with an add-reference and remove-reference method, and when there are no manually-tracked references anymore then entry can be deleted, leaving future lookups on that key to return null.
This is not really a weakref, but it can solve some of the same problems. It's typically done in complex web applications to prevent memory leakage from browsers (typically IE, especially older versions) when there is a reference loop between a DOM Node or event handler, and an object associated with it such as a closure. In these cases a full reference-counting scheme may not even be necessary.
When running JS on NodeJS, you may consider https://github.com/TooTallNate/node-weak.
Update: September 2019
It is not possible to use weak references yet, but most likely soon it will be possible, as WeakRefs in JavaScript are Work In Progress. Details below.
Proposal
Proposal in now in Stage 3 which means that it has complete specification and that further refinement will require feedback from implementations and users.
The WeakRef proposal encompasses two major new pieces of functionality:
- Creating weak references to objects with the WeakRef class
- Running user-defined finalizers after objects are garbage-collected, with the FinalizationGroup class
Use cases
A primary use for weak references is to implement caches or mappings holding large objects, where it’s desired that a large object is not kept alive solely because it appears in a cache or mapping.
Finalization is the execution of code to clean up after an object that has become unreachable to program execution. User-defined finalizers enable several new use cases, and can help prevent memory leaks when managing resources that the garbage collector doesn't know about.
Source and further reading
https://github.com/tc39/proposal-weakrefs
https://v8.dev/features/weak-references
2021 Update
WeakRef
is now implemented in Chrome, Edge, and Firefox. Still waiting on Safari and some other holdouts.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakRef
May 2021 Update It's now available on Safari thus all major browsers. See above.
Just for reference; JavaScript doesn't have it, but ActionScript 3 (which is also ECMAScript) does. Check out the constructor parameter for Dictionary.