Is there any way in JavaScript to create a "weak reference" to another object? Here is the wiki page describing what a weak reference is. Here is another article that describes them in Java. Can anyone think of a way to implement this behavior 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.
Finally they are here. Not yet implemented in browsers, but soon to be.
True weak references, no, not yet (but browser makers are looking at the subject). But here is an idea on how to simulate weak references.
You could build a cache which you drive your objects through. When an object is stored, the cache keeps a prediction of how much memory the object will take up. For some items, like storing images, this is straight forward to work out. For others this would be more difficult.
When you need an object, you then ask the cache for it. If the cache has the object, it is returned. If it is not there, then the item is generated, stored, and then returned.
The weak references are simulated by the cache removing items, when the total amount of predicted memory reaches a certain level. It will predict which items are least used based on how often they are retrieved, weighted by how long ago they were taken out. A 'calculation' cost could also be added, if the code that creates the item is passed into the cache as a closure. This would allow the cache to keep items which are very expensive to build or generate.
The deletion algorithm is key, because if you get this wrong then you could end up removing the most popular items. This would cause terrible performance.
As long as the cache is the only object with permanent references to the objects stored, then the above system should work pretty well as an alternative to true weak references.
Using a caching mechanism to emulate a weak reference, as JL235 suggested above, is reasonable. If weak references would exist natively, you would observe a behavior like this:
this.val = {};
this.ref = new WeakReference(this.val);
...
this.ref.get(); // always returns val
...
this.val = null; // no more references
...
this.ref.get(); // may still return val, depending on already gc'd or not
Whereas with a cache you would observe:
this.val = {};
this.key = cache.put(this.val);
...
cache.get(this.key); // returns val, until evicted by other cache puts
...
this.val = null; // no more references
...
cache.get(this.key); // returns val, until evicted by other cache puts
As a holder of a reference, you should not make any assumptions about when it refers to a value, this is no different using a cache
EcmaScript 6 (ES Harmony) has a WeakMap object. Browser support amongst modern browsers is pretty good (the last 3 versions of Firefox, chrome and even an upcoming IE version support it).
WeakMap
doesn't give weak references to objects-- it is not the values that are weak references in WeakMap, but the keys. The fact that weak references exist in the map is only a memory leak prevention mechanism, and is not observable to the user otherwise. –
Tricuspid weakmap.get(new String('any possible key that has ever existed or ever will exist'))
will always be undefined
. Not useful. Down-voting! –
Shimmer http://www.jibbering.com/faq/faq_notes/closures.html
ECMAScript uses automatic garbage collection. The specification does not define the details, leaving that to the implementers to sort out, and some implementations are known to give a very low priority to their garbage collection operations. But the general idea is that if an object becomes un-referable (by having no remaining references to it left accessible to executing code) it becomes available for garbage collection and will at some future point be destroyed and any resources it is consuming freed and returned to the system for re-use.
This would normally be the case upon exiting an execution context. The scope chain structure, the Activation/Variable object and any objects created within the execution context, including function objects, would no longer be accessible and so would become available for garbage collection.
Meaning there are no weak ones only ones that no longer become available.
© 2022 - 2024 — McMap. All rights reserved.