JavaScript WeakMap et WeakSet
Dans le chapitre Collection d'ordures, il a été déclaré que le moteur JavaScript peut stocker une valeur en mémoire une fois qu'elle est atteignable.
Voici un exemple:
En règle générale, les propriétés ou éléments de structures de données telles qu'un objet ou un tableau sont atteignables et conservés en mémoire une fois que cette structure de données est en mémoire. Par exemple, après avoir mis un objet dans un tableau, il existera aussi longtemps que le tableau existera.
Voici un exemple:
De manière correspondante, l'application d'un objet comme la clé dans un Map régulière, il existera aussi longtemps que le plan existe.
Un exemple ressemblera à ce qui suit:
De plus, nous allons couvrir WeakMap, qui est complètement différent et ne s'abstient pas de la collecte d'ordures des objets clés.
WeakMap
La principale différence entre Map et WeakMap est que la clé du WeakMap ne peut pas être des valeurs primitives. Ils doivent être des objets, comme dans l'exemple ci-dessous:
Les itérations et les méthodes keys(), values(), entries() ne sont pas supportées par WeakMap.
Les méthodes, supportées par WeakMap sont les suivantes: weakMap.get(key), weakMap.set(key, value), weakMap.has(key), et weakMap.delete(key).
weakMap.delete(key)
Le stockage supplémentaire de données est le principal domaine d'application pour WeakMap. WeakMap est particulièrement utile pour stocker des données associées à une bibliothèque tierce. Par exemple, envisagez de mettre les données dans un WeakMap, avec un objet comme clé. Une fois l'objet collecté comme ordure, les données disparaîtront également automatiquement comme le montre ci-dessous:
let weakMap = new WeakMap();
let obj = {
name: "test"
};
key = weakMap.set(obj, "test docs");
// if obj disappears, test docs will be automatically destroyed
Maintenant, imaginez avoir un code qui maintient un compteur de visites pour les utilisateurs. L'information est conservée dans une carte, avec un objet utilisateur comme clé et le nombre de visites comme valeur.
Après le départ d'un utilisateur, vous avez l'intention d'arrêter de stocker leur nombre de visites.
Tout d'abord, voyons un exemple de fonction de comptage avec Map. Cela ressemblera à ce qui suit:
Ainsi, lors de la suppression des utilisateurs, il est nécessaire de nettoyer visitsCountMap. D'une autre manière, il sera stocké en mémoire indéfiniment.
Cependant, le nettoyage de cette façon peut parfois devenir une tâche ennuyeuse. Si vous voulez l'éviter, vous pouvez vous référer à WeakMap. Voici un exemple d'utilisation de WeakMap à la place de ce genre de nettoyage:
Maintenant, il n'est plus nécessaire de nettoyer visitsCountMap.
A propos du Caching
Le caching se produit lorsqu'un résultat de fonction doit être mémorisé (mis en cache) pour être réutilisé plus tard lors de l'appel sur le même objet.
Map peut être utilisé pour stocker les résultats comme suit:
Dans le cas de l'appel à process(obj) avec le même objet plusieurs fois, il calculera le résultat seulement la première fois. Ensuite, il prendra l'information du cache.
Le seul inconvénient du caching est que vous devez nettoyer le cache une fois que vous n'avez plus besoin de l'objet.
Remplacer Map par WeakMap résoudra le problème. L'information mise en cache sera supprimée de la mémoire automatiquement une fois que l'objet aura été collecté comme ordure.
Pour être plus précis, considérons l'exemple ci-dessous:
// cache.js
let cache = new WeakMap();
// calculate and remember the result
function process(obj) {
if (!cache.has(obj)) {
let res = /* calculate the result for */ obj;
cache.set(obj, res);
}
return cache.get(obj);
}
// main.js
let obj = { /* some object */ };
let res1 = process(obj);
let res2 = process(obj);
// later, when object is no longer needed:
obj = null;
// Can not get cache.size because it is WeakMap,
// but it is 0 or soon will be 0
//Once object gets garbage collected, the cached data will also be cleaned
WeakSet
WeakSet est considéré comme équivalent à Set. Cependant, seuls les objets et non les primitives peuvent être ajoutés à WeakSet.
Un objet est situé dans l'ensemble tant qu'il est atteignable ailleurs.WeakSet prend également en charge has, add et delete. Mais il n'y a pas d'itérations ou de size et de keys() qui sont supportées.
De plus, il peut servir de stockage supplémentaire pour les données, mais pas pour des données arbitraires. Voici un exemple d'ajout de langues à WeakSet pour garder une trace de celles qui ont créé le site:
Il y a une limitation significative dans WeakMap et WeakSet: il n'y a pas d'itérations. Il n'y a pas non plus de possibilité de recevoir tout le contenu actuel.
Résumé
Dans ce chapitre, nous avons couvert WeakMap et WeakSet.
En résumé, nous pouvons dire que WeakMap est considéré comme une collection de type Map, permettant uniquement aux objets d'être des clés. Il les supprime ainsi que la valeur associée lorsqu'ils deviennent inaccessibles.
WeakSet est considéré comme une collection de type Set, ne stockant que des objets et les supprimant lorsqu'ils deviennent inaccessibles.
Les deux collections ne supportent pas les propriétés et méthodes ne se référant pas à toutes les clés ou au comptage de celles-ci. Ils ne permettent que des opérations individuelles.
Heure du Quiz : Testez Vos Compétences!
Prêt à relever le défi de ce que vous avez appris ? Plongez dans nos quiz interactifs pour approfondir votre compréhension et renforcer vos connaissances de manière ludique.