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?
-
Just for reference; JavaScript doesn't have it, but ActionScript 3 (which is also ECMAScript) does. Check out the constructor parameter for Dictionary.– AmirCommented Mar 23, 2010 at 18:12
-
4Weak references are being discussed for ES6. Keep your eyes peeled.– Ryan SmithCommented Mar 2, 2013 at 15:59
-
2*Official spec wiki/discussion at wiki.ecmascript.org/doku.php?id=strawman:weak_refs, currently “Last modified: 2013/02/02 22:25” *some other spec discussion at esdiscuss.org/topic/what-is-the-status-of-weak-references, currently last post “Sun Mar 3 11:56:05 PST 2013”– Destiny ArchitectCommented Oct 25, 2014 at 4:21
-
In most cases WRs are an attempt to solve the Lapsed Listener Problem, discussed here: [stackoverflow.com/questions/43758217/…. If that question had a good answer I don't think there would be much need for WRs.– JamesCommented Apr 27, 2018 at 11:11
-
@supercat I have posted an answer to the lapsed listener question.– JamesCommented Aug 18, 2018 at 18:23
9 Answers
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.
-
2I haven't carefully examined (or used) the code, but es-lab has a script providing basic WeakMap emulation. Aurora 6 (Mozilla) has a non-standard WeakMap implementation. Commented Jun 17, 2011 at 8:04
-
2With ES6 this answer is no longer correct. See my answer below stackoverflow.com/a/28567560/745190 Commented Mar 16, 2015 at 13:02
-
9It's still correct, because ES6 WeakMaps aren't true weak references. WeakMaps accept objects as keys only, and the references to these objects are held weakly. See stackoverflow.com/questions/32397729/…– CodeManXCommented Sep 4, 2015 at 13:24
-
I wrote a class to emulate a weak map and posted it here: stackoverflow.com/a/47017206/491553 Commented Oct 30, 2017 at 14:05
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
-
1Firefox Nightly has added experimental support for WeakRef. Here's an example implementation using it to create an iterable version of WeakSet: gist.github.com/seanlinsley/bc10378fd311d75cf6b5e80394be813d Commented Mar 21, 2020 at 21:03
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.
-
25
-
22@JL235 -- the important use for weak references is not for caches but for event-handlers. I have some object that, while it exists, should observe some other event -- but I don't want the fact that it is in a notification-list to constitute a reference for the purposes of GC. Commented May 1, 2012 at 19:10
-
7Weak references are nothing to do with caching. A weak reference means you want to keep track of something, but if there are no remaining references to the object being tracked, you allow it to be deleted.– fabsproCommented May 31, 2013 at 8:29
-
8There's clearly a use case for building a cache using weak references for automatic expiry. Commented Aug 8, 2013 at 18:00
-
5Caching is the traditionally a top reason for weak references. The event handler DOM thing is only some IE explorer buggy thing.– axkibeCommented Dec 18, 2013 at 9:28
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).
-
30This isn't exactly the same. A
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.– EyasSHCommented May 8, 2015 at 21:07 -
1You're correct that it's the keys that are weak, not the values. But the whole purpose of using weak references is to allow garbage collection of the referenced object. The OP posted two links, the second of which is about adding an id to an object you can't extend, and in fact it recommends using WeakHashMap, the Java equivalent of JavaScript's WeakMap. Commented May 11, 2015 at 9:04
-
12good luck using WeakMap to implement a weak reference since
weakmap.get(new String('any possible key that has ever existed or ever will exist'))
will always beundefined
. Not useful. Down-voting! Commented May 11, 2016 at 23:58
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.
-
10Avoiding reference cycles isn't the only reason to use weak references. They're very handy for object instance pooling/caching and so on.– fluffyCommented Jun 4, 2011 at 6:53
-
Definition of WeakReference is not an of the question. Also as agree with comment above. Commented May 22, 2018 at 7:05