Recherche este y este Dans les pages MDN, il semble que la seule différence entre Maps et WeakMaps soit l'absence de la propriété "size" pour WeakMaps. Mais est-ce vrai ? Quelle est la différence entre les deux ?
Réponses
Trop de publicités?Ils se comportent tous deux différemment lorsqu'un objet référencé par leurs clés/valeurs est supprimé. Prenons l'exemple de code ci-dessous :
var map = new Map();
var weakmap = new WeakMap();
(function(){
var a = {x: 12};
var b = {y: 12};
map.set(a, 1);
weakmap.set(b, 2);
})()
Le IIFE ci-dessus est exécuté, il n'y a aucun moyen de référencer {x: 12}
y {y: 12}
plus. Le collecteur d'ordures va de l'avant et supprime le pointeur de la clé b de "WeakMap" et supprime également {y: 12}
de mémoire. Mais dans le cas de "Map", le ramasseur d'ordures ne supprime pas un pointeur de "Map" et ne supprime pas non plus les éléments suivants {x: 12}
de mémoire.
Résumé : WeakMap permet au ramasseur d'ordures d'effectuer sa tâche mais pas à Map.
Références : http://qnimate.com/difference-between-map-and-weakmap-in-javascript/
Peut-être que la prochaine explication sera plus claire pour quelqu'un.
var k1 = {a: 1};
var k2 = {b: 2};
var map = new Map();
var wm = new WeakMap();
map.set(k1, 'k1');
wm.set(k2, 'k2');
k1 = null;
map.forEach(function (val, key) {
console.log(key, val); // k1 {a: 1}
});
k2 = null;
wm.get(k2); // undefined
Comme vous le voyez, après avoir retiré k1
de la mémoire, nous pouvons toujours y accéder dans la carte. En même temps, le fait de retirer k2
de WeakMap l'enlève de wm
ainsi que par référence.
C'est pourquoi WeakMap n'a pas de méthodes énumérables comme forEach, parce qu'il n'existe pas de liste de clés WeakMap, ce sont juste des références à d'autres objets.
En à la même page, section " Pourquoi Faible Une carte ? " :
Le programmeur JavaScript expérimenté remarquera que cette API pourrait être implémentée en JavaScript avec deux tableaux (un pour les clés, un pour les valeurs) partagés par les 4 méthodes de l'API. Une telle implémentation aurait deux inconvénients principaux. Le premier est une recherche de O(n) (n étant le nombre de clés dans la carte). Le second est un problème de fuite de mémoire. Avec des cartes écrites manuellement, le tableau de clés conserverait les références à objets clés, les empêchant d'être ramassés. Dans les WeakMaps natives, les références aux objets clés sont conservées. "faiblement" ce qui signifie qu'ils n'empêchent pas la collecte des déchets au cas où il n'y aurait pas autre référence à l'objet.
Comme les références sont faibles, les clés WeakMap ne sont pas énumérables. (c'est-à-dire qu'il n'existe pas de méthode permettant d'obtenir une liste des clés). Si elles l'étaient la liste dépendrait de l'état du ramassage des déchets, ce qui introduirait non-déterminisme.
[Et c'est pourquoi ils n'ont pas size
également la propriété]
Si vous voulez avoir une liste de clés, vous devez la tenir à jour vous-même. Il existe également une ECMAScript proposition visant à introduire des ensembles et des cartes simples qui n'utiliseraient pas de faibles et qui seraient énumérables.
- qui serait le "normal" Map
s . Non mentionné à MDN, mais dans le proposition d'harmonie Ceux-ci ont également items
, keys
y values
et mettre en œuvre les méthodes du générateur Iterator
interface .
Une autre différence (source : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap ):
Les clés de WeakMaps sont uniquement de type Object. Les types de données primitifs comme ne sont pas autorisés (par exemple, un symbole ne peut pas être une clé de WeakMap).
Une chaîne de caractères, un nombre ou un booléen ne peut pas non plus être utilisé comme un WeakMap
clé. A Map
puede utiliser des valeurs primitives pour les clés.
w = new WeakMap;
w.set('a', 'b'); // Uncaught TypeError: Invalid value used as weak map key
m = new Map
m.set('a', 'b'); // Works
En Javascript.info
Carte -- Si nous utilisons un objet comme clé dans une Map ordinaire, alors tant que la Map existe, cet objet existe également. Il occupe de la mémoire et peut ne pas être récupéré par les ordures.
let john = { name: "John" };
let array = [ john ];
john = null; // overwrite the reference
// john is stored inside the array, so it won't be garbage-collected
// we can get it as array[0]
De la même manière, si nous utilisons un objet comme clé dans une Map ordinaire, alors tant que la Map existe, cet objet existe également. Il occupe de la mémoire et peut ne pas être récupéré par les ordures ménagères.
let john = { name: "John" };
let map = new Map();
map.set(john, "...");
john = null; // overwrite the reference
// john is stored inside the map,
// we can get it by using map.keys()
WeakMap -- Maintenant, si nous utilisons un objet comme clé dans cette carte, et qu'il n'y a pas d'autres références à cet objet - il sera supprimé de la mémoire (et de la carte) automatiquement.
let john = { name: "John" };
let weakMap = new WeakMap();
weakMap.set(john, "...");
john = null; // overwrite the reference
// john is removed from memory!
- Réponses précédentes
- Plus de réponses