web-dev-qa-db-fra.com

Est-il possible de créer une "référence faible" en javascript?

Existe-t-il un moyen en javascript pour créer une "référence faible" à un autre objet? Voici la page wiki décrivant ce qu'est une référence faible.Voici un autre article qui les décrit en Java. Quelqu'un peut-il penser à un moyen de mettre en œuvre ce comportement en javascript?

85
Stephen Cagle

Il n'y a pas de support de langue pour les références faibles en JavaScript. Vous pouvez rouler le vôtre en utilisant le comptage manuel des références, mais pas particulièrement en douceur. Vous ne pouvez pas créer un objet wrapper proxy, car en JavaScript, les objets ne savent jamais quand ils sont sur le point d'être récupérés.

Ainsi, votre "référence faible" devient une clé (par exemple, un entier) dans une recherche simple, avec une méthode d'ajout de référence et de suppression de référence, et lorsqu'il n'y a plus de références suivies manuellement, l'entrée peut être supprimée, laissant les futures recherches sur cette clé pour retourner null.

Ce n'est pas vraiment une référence faible, mais cela peut résoudre certains des mêmes problèmes. Il est généralement effectué dans des applications Web complexes pour éviter les fuites de mémoire des navigateurs (généralement IE, en particulier les anciennes versions) lorsqu'il existe une boucle de référence entre un DOM Node ou gestionnaire d'événements, et un objet qui lui est associé Dans ces cas, un système complet de comptage des références peut même ne pas être nécessaire.

37
bobince

Lorsque vous exécutez JS sur NodeJS, vous pouvez considérer https://github.com/TooTallNate/node-weak .

14
Scholle

De vraies références faibles, non, pas encore (mais les fabricants de navigateurs se penchent sur le sujet). Mais voici une idée sur la façon de simuler des références faibles.

Vous pouvez créer un cache à travers lequel vous conduisez vos objets. Lorsqu'un objet est stocké, le cache conserve une prédiction de la quantité de mémoire que l'objet prendra. Pour certains éléments, comme le stockage d'images, c'est simple à comprendre. Pour d'autres, ce serait plus difficile.

Lorsque vous avez besoin d'un objet, vous le demandez ensuite au cache. Si le cache contient l'objet, il est renvoyé. S'il n'y figure pas, l'élément est généré, stocké, puis renvoyé.

Les références faibles sont simulées par les éléments de suppression de cache, lorsque la quantité totale de mémoire prédite atteint un certain niveau. Il permettra de prédire quels articles sont les moins utilisés en fonction de la fréquence à laquelle ils sont récupérés, pondérés en fonction de la durée de leur retrait. Un coût de "calcul" pourrait également être ajouté, si le code qui crée l'élément est passé dans le cache en tant que fermeture. Cela permettrait au cache de conserver des éléments très coûteux à construire ou à générer.

L'algorithme de suppression est essentiel, car si vous vous trompez, vous pourriez finir par supprimer les éléments les plus populaires. Cela entraînerait de terribles performances.

Tant que le cache est le seul objet avec des références permanentes aux objets stockés, le système ci-dessus devrait fonctionner plutôt bien comme alternative aux vraies références faibles.

3
JL235

Juste pour référence; JavaScript ne l'a pas, mais ActionScript 3 (qui est également ECMAScript). Consultez le paramètre constructeur pour Dictionary .

2
Amir

Ils sont enfin là. Pas encore implémenté dans les navigateurs, mais bientôt.

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

1
Goran Jakovljevic

L'utilisation d'un mécanisme de mise en cache pour émuler une référence faible, comme JL235 suggéré ci-dessus , est raisonnable. Si des références faibles existaient nativement, vous observeriez un comportement comme celui-ci:

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

Alors qu'avec une cache, vous observeriez:

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

En tant que détenteur d'une référence, vous ne devez pas faire d'hypothèses sur le moment où il se réfère à une valeur, ce n'est pas différent en utilisant un cache

1
Markus