javascript
ecmascript-6
ecmascript-harmony
weakmap
Dmitrii Sorin
źródło
źródło
key
nie można zebrać, ponieważ odwołujesz się do niego.Odpowiedzi:
Na tej samej stronie w sekcji „ Dlaczego słaba mapa? ” :
[I dlatego też nie mają
size
własności]- czyli „normalne”
Map
s . Niewymienionych w MDN, ale na wniosek harmonii , ci mają równieżitems
,keys
ivalues
metody generatora oraz wdrożenieIterator
interfejsu .źródło
new Map().get(x)
jest mniej więcej taki sam, jak odczyt właściwości ze zwykłego obiektu?WeakMap
nadal ma tablicę (lub inną kolekcję) wpisów, po prostu informuje moduł odśmiecania pamięci, że są to słabe odwołania .Oba zachowują się inaczej, gdy obiekt, do którego odwołują się ich klucze / wartości, zostanie usunięty. Weźmy poniższy przykładowy kod:
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); })()
Powyższy IIFE jest wykonywany, nie ma możliwości odniesienia się do niego
{x: 12}
i{y: 12}
już. Moduł wyrzucania elementów bezużytecznych działa dalej i usuwa wskaźnik klawisza b z „WeakMap”, a także usuwa{y: 12}
z pamięci. Ale w przypadku „Mapy”, garbage collector nie usuwa wskaźnika z „Map”, a także nie usuwa{x: 12}
z pamięci.Podsumowanie: WeakMap pozwala garbage collectorowi wykonywać swoje zadanie, ale nie Map.
Źródła : http://qnimate.com/difference-between-map-and-weakmap-in-javascript/
źródło
map.entries().next().value // [{x:12}, 1]
WeakMap
może mieć tylko nieprymitywne klucze (bez łańcuchów, liczb lubSymbol
s jako kluczy, tylko tablice, obiekty, inne mapy itp.).Map
ale nie wWeakMap
Może następne wyjaśnienie będzie dla kogoś bardziej jasne.
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
Jak widzisz, po wyjęciu
k1
klucza z pamięci nadal mamy do niego dostęp wewnątrz mapy. W tym samym czasie usunięciek2
klucza WeakMap usuwa gowm
również przez odniesienie.Dlatego WeakMap nie ma wyliczalnych metod, takich jak forEach, ponieważ nie ma czegoś takiego jak lista kluczy WeakMap, są one po prostu odniesieniami do innych obiektów.
źródło
forEach
,(key, val)
należy być w rzeczywistości(val, key)
Kolejna różnica (źródło: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap ):
Jako
WeakMap
klucza nie można też użyć ciągu, liczby ani wartości logicznej . AMap
może używać wartości pierwotnych dla kluczy.w = new WeakMap; w.set('a', 'b'); // Uncaught TypeError: Invalid value used as weak map key m = new Map m.set('a', 'b'); // Works
źródło
Z Javascript.info
Mapa - jeśli używamy obiektu jako klucza w zwykłej mapie, to gdy mapa istnieje, ten obiekt również istnieje. Zajmuje pamięć i nie może być usuwany jako śmieci.
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]
Podobnie, jeśli używamy obiektu jako klucza w zwykłej Mapie, to gdy Mapa istnieje, ten obiekt również istnieje. Zajmuje pamięć i nie może być usuwany jako śmieci
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 - Teraz, jeśli użyjemy w nim obiektu jako klucza i nie ma innych odniesień do tego obiektu - zostanie on automatycznie usunięty z pamięci (i mapy).
let john = { name: "John" }; let weakMap = new WeakMap(); weakMap.set(john, "..."); john = null; // overwrite the reference // john is removed from memory!
źródło
WeapMap w javascript nie przechowuje żadnych kluczy ani wartości, po prostu manipuluje wartością klucza przy użyciu unikalnego identyfikatora i definiuje właściwość obiektu klucza.
ponieważ definiuje właściwość
key object
według metodyObject.definePropert()
, klucz nie może być typem pierwotnym .a także ponieważ WeapMap nie zawiera w rzeczywistości par klucz-wartość, nie możemy uzyskać właściwości length ze słabe mapy.
a także manipulowana wartość jest przypisywana z powrotem do obiektu klucza, moduł odśmiecania pamięci może łatwo zebrać klucz, jeśli nie jest używany.
Przykładowy kod do implementacji.
if(typeof WeapMap != undefined){ return; } (function(){ var WeapMap = function(){ this.__id = '__weakmap__'; } weakmap.set = function(key,value){ var pVal = key[this.__id]; if(pVal && pVal[0] == key){ pVal[1]=value; }else{ Object.defineProperty(key, this.__id, {value:[key,value]}); return this; } } window.WeakMap = WeakMap; })();
odniesienie do realizacji
źródło
id
, ale powinno to być unikalne przez użycie czegoś Math.random i Date.now (), itp. I dodając ten dynamiczny identyfikator, można rozwiązać pierwszy punkt. Czy mógłbyś podać mi rozwiązanie dwóch ostatnich punktów.WeakMap
klucze muszą być obiektami, a nie wartościami pierwotnymi.let weakMap = new WeakMap(); let obj = {}; weakMap.set(obj, "ok"); // works fine (object key) // can't use a string as the key weakMap.set("test", "Not ok"); // Error, because "test" is not an object
Czemu????
Zobaczmy poniższy przykład.
let user = { name: "User" }; let map = new Map(); map.set(user, "..."); user = null; // overwrite the reference // 'user' is stored inside the map, // We can get it by using map.keys()
let user = { name: "User" }; let weakMap = new WeakMap(); weakMap.set(user, "..."); user = null; // overwrite the reference // 'user' is removed from memory!
WeakMap
nie obsługuje iteracji i metod keys () , values () , entry () , więc nie ma możliwości uzyskania z nich wszystkich kluczy lub wartości.WeakMap ma tylko następujące metody:
Jest to oczywiste, tak jakby obiekt stracił wszystkie inne odniesienia (jak „user” w powyższym kodzie), to ma zostać automatycznie zebrany jako śmieci. Ale technicznie nie jest dokładnie określone, kiedy nastąpi czyszczenie.
Decyduje o tym silnik JavaScript. Może zdecydować się na natychmiastowe wyczyszczenie pamięci lub zaczekać i wykonać czyszczenie później, gdy nastąpi więcej usunięć. Tak więc technicznie aktualna liczba elementów a
WeakMap
nie jest znana. Silnik mógł go wyczyścić lub nie, lub zrobił to częściowo. Z tego powodu metody uzyskujące dostęp do wszystkich kluczy / wartości nie są obsługiwane.źródło