31

Before my re-entry in JavaScript (and related) I've done lots of ActionScript 3 and there they had a Dictionary object that had weak keys just like the upcoming WeakMap; but the AS3 version still was enumerable like a regular generic object while the WeakMap specifically has no .keys() or .values().

The AS3 version allowed us to rig some really interesting and usefull constructs but I feel the JS version is somewhat limited. Why is that?

If the Flash VM could do it then what is keeping browsers from doing same? I read how it would be 'non-deterministic' but that is sort of the point right?

Bergi
  • 513,640
  • 108
  • 821
  • 1,164
Bartvds
  • 2,809
  • 3
  • 25
  • 40
  • 8
    I think the [MDN entry](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap) sums it up pretty well: "Because of references being weak, WeakMap keys are not enumerable (i.e. there is no method giving you a list of the keys). If they were, the list would depend on the state of garbage collection, introducing non-determinism." It's not that rules couldn't be defined, but by not allowing the operation to begin with the implementations (of which there are several competing) can side-step the issue entirely. – user2864740 Dec 11 '13 at 01:10
  • Sure, that makes some sense but it a little weak (hehehe) of the standard committee. I'm still hoping for some insight on why ennumerability is not important enough to be a required feature. – Bartvds Dec 16 '13 at 19:46
  • Sure, but quoting MDN: "to prevent you from using an array of keys keeping references to key objects, preventing them from being garbage collected" and "If you want to have a list of keys, you should maintain it yourself". So to get enumerability i use a WeakMap and an array of keys. Completely nullifying the value of WeakMap. So how do i have enumerable weak references???????? – bernstein May 12 '14 at 22:59
  • 2
    @bernstein you don't. The weak map is intended to be used for cache implementations and things like that, where other parts of your application know about keys that *might* be in the map. – Pointy May 17 '14 at 15:37
  • 2
    What? No it is not. This is not about the basic Map, but is a very specific Weakmap question. The referred item doesn't answer the question, just like other answers here it ignores the fact that the AS3 version worked fine with non-determinism. – Bartvds Jun 23 '14 at 14:51
  • 1
    @Pointy The fact that the key must be an object and must not be a primitive data type, makes it impossible for most use cases to use the WeakMap as a cache. A web cache uses URLs (a string) and DAO classes use OIDs (integer) as keys for the cache. Both use cases are impossible with objects as keys. – ceving Nov 04 '15 at 13:04
  • @ceving surely you can wrap a string key in a String instance. *edit* oh wait that won't work. Well you could use Symbols. Wait, that won't work either. OK now I see what you mean :) – Pointy Nov 04 '15 at 14:10
  • [Here's another SSO question and a great use-case explanation in the top answer.](http://stackoverflow.com/questions/29413222/what-are-the-actual-uses-of-es6-weakmap) – Pointy Nov 04 '15 at 14:28

2 Answers2

19

Finally found the real answer: http://tc39wiki.calculist.org/es6/weak-map/

A key property of Weak Maps is the inability to enumerate their keys. This is necessary to prevent attackers observing the internal behavior of other systems in the environment which share weakly-mapped objects. Should the number or names of items in the collection be discoverable from the API, even if the values aren't, WeakMap instances might create a side channel where one was previously not available.

Bartvds
  • 2,809
  • 3
  • 25
  • 40
  • 1
    thanks. a lot. so its a misnomer and it should be named SecretKeyAndWeakMap. *Anyone having attended SE 101 starts crying* – bernstein Sep 15 '14 at 16:18
  • 2
    This answer presumes “in the environment which share weakly-mapped objects” -but is that common? -I never heard of it before. Moreover, why whould that be necessary? -And if it was, just create for instance of a WeakMap its own special internal collection of weak pointers, as indeed the WeakMap object suggests by its name & definition (that it's a map so collection), so again, if there is/must-be sharing, seems no problem that the WeakMap instance be implemented to create is own collection. So I don't see this answers (yet?) Why. – Destiny Architect Nov 09 '14 at 07:48
  • 16
    This is disappointing. Not being able to enumerate the weak collection really limits its usefulness. – Brandon Feb 26 '15 at 12:36
  • 5
    I don't think this is actually it. I think this was more about being able to observe GC. If you allow enumerating WeakMaps you're exposing the developer to a form of indeterminism since they can now observe GC and memory where atm they can't. – Benjamin Gruenbaum Apr 02 '15 at 18:48
  • 1
    Looks like JavaScript will finally be getting a _true_ WeakReference implementation in the future! https://stackoverflow.com/a/58009243/2441655 This would enable an iterable WeakMap, by combining the two. (create an array of WeakRefs to each of the keys in the WeakMap, then iterate by iterating through keys and just combining each with the in-WeakMap value) – Venryx Nov 16 '19 at 09:59
  • Firefox Nightly has added experimental support for WeakRef. Here's an example implementation using it to create an iterable version of WeakSet: https://gist.github.com/seanlinsley/bc10378fd311d75cf6b5e80394be813d. The specification linked there also includes an implementation for WeakMap. – seanlinsley Mar 21 '20 at 21:42
0

It's a tradeoff. If you introduce object <-> object dictionaries that support enumerability, you have two options with relation to garbage collection:

  1. Consider the key entry a strong reference that prevents garbage collection of the object that's being used as a key.

  2. Make it a weak reference that allows its keys to be garbage collected whenever every other reference is gone.

If you do #1 you will make it extremely easy to to shoot yourself in the foot by leaking large objects into memory all over the place. On the other hand, if you go with option #2, your key dictionary becomes dependent on the state of garbage collection in the application, which will inevitably lead to impossible to track down bugs.

  • 6
    Again, as described in the OP and other comments: AS3 had weak keys that were still enumerable. It worked fine and allowed to collect/associate values without blocking GC. You could then loop the keys to do stuff with the keys that weren't collected yet. – Bartvds Jun 30 '14 at 20:10
  • 1
    That is non-deterministic behavior, which was case #2 of my explanation, and is what creates the side-channel described in your other answer. – user3550896 Jul 31 '14 at 00:19