It also doesn't hurt performance like scanning the WeakMaps on every such object's release would, and the object is otherwise completely unlinked anyway, so it doesn't keep unnecessary refs in the meantime.
You don't need to scan for every WeakMap if you store enough info. One solution would be to use a separate struct as a key: an object could allocate such struct on demand and store it. That struct could store a reference a weak reference to the original object and object destructor would just reset that reference. See Gecko's `nsWeakReference` and `nsSupportsWeakReference` for examples.
The downside of the above solution is that it still delays the actual weak map destruction to GC. We could extend it to store the whole list of entries where an object is used as a key to clean them directly from object destructor. (We'd probably want to try to avoid bloating `jsdisp_t` too much while implementing it, but it seems doable).