Is it possible to create a "weak reference" in JavaScript?

JavascriptWeak References

Javascript Problem Overview


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?

Javascript Solutions


Solution 1 - Javascript

Update: Since July, 2020 some implementations (Chrome, Edge, Firefox and Node.js) has had support for WeakRefs 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.

Solution 2 - Javascript

When running JS on NodeJS, you may consider https://github.com/TooTallNate/node-weak.

Solution 3 - Javascript

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

Solution 4 - Javascript

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.

Solution 5 - Javascript

Just for reference; JavaScript doesn't have it, but ActionScript 3 (which is also ECMAScript) does. Check out the constructor parameter for Dictionary.

Solution 6 - Javascript

Finally they are here. Not yet implemented in browsers, but soon to be.

https://v8.dev/features/weak-references

Solution 7 - Javascript

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.

Solution 8 - Javascript

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

Solution 9 - Javascript

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).

Solution 10 - Javascript

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionStephen CagleView Question on Stackoverflow
Solution 1 - JavascriptbobinceView Answer on Stackoverflow
Solution 2 - JavascriptScholleView Answer on Stackoverflow
Solution 3 - JavascriptM. TwarogView Answer on Stackoverflow
Solution 4 - JavascriptPeter MooreView Answer on Stackoverflow
Solution 5 - JavascriptAmirView Answer on Stackoverflow
Solution 6 - JavascriptGoran JakovljevicView Answer on Stackoverflow
Solution 7 - JavascriptJL235View Answer on Stackoverflow
Solution 8 - JavascriptMarkusView Answer on Stackoverflow
Solution 9 - JavascriptthelastshadowView Answer on Stackoverflow
Solution 10 - JavascriptbranchgabrielView Answer on Stackoverflow