18

Po przeczytaniu tego opisu: http://wiki.ecmascript.org/doku.php?id=harmony:weak_mapsCo to są ECMAScript 6 WeakMaps?

Próbuję to zrozumieć, ale nie mam ogólnego obrazu. O co w tym wszystkim chodzi? To wydaje się być obsługiwane w Firefox 6: http://kangax.github.com/es5-compat-table/non-standard/

+0

Wszystkie odpowiedzi są błędne. Jedyną "słabą" w słabej mapie są klucze. To znaczy - jeśli masz klucz-wartość na słabej mapie, w przeciwieństwie do zwykłej "mapy", to nie zapobiegnie to, że zostanie ona zebrana. Jest to użyteczne na przykład do rozszerzania obiektów z zewnątrz bez bałaganu przy zbieraniu śmieci. W szczególności odpowiedź Raynos wyjaśnia, czym jest mapa. –

+2

Powiązane: [Jakie są rzeczywiste zastosowania ESak WeakMap?] (Http://stackoverflow.com/q/29413222/1114) –

+0

** Ostrzeżenie: obie odpowiedzi tutaj są niepoprawne **. Zobacz post połączony z komentarzem powyżej, aby uzyskać sensowne odpowiedzi. –

Odpowiedz

11

WeakMap

WeakMaps zasadzie pozwalają mieć hashtable z kluczem, który nie jest łańcuchem.

Więc można ustawić klucz być, czyli [1] i wtedy można powiedzieć Map.get([1])

przykład z MDN:

var wm1 = new WeakMap(), 
    wm2 = new WeakMap(); 
var o1 = {}, 
    o2 = function(){}, 
    o3 = window; 

wm1.set(o1, 37); 
wm1.set(o2, "azerty"); 
wm2.set(o1, o2); // a value can be anything, including an object or a function 
wm2.set(o3, undefined); 
wm2.set(wm1, wm2); // keys and values can be any objects. Even WeakMaps! 

wm1.get(o2); // "azerty" 
wm2.get(o2); // undefined, because there is no value for o2 on wm2 
wm2.get(o3); // undefined, because that is the set value 

wm1.has(o2); // true 
wm2.has(o2); // false 
wm2.has(o3); // true (even if the value itself is 'undefined') 

wm1.has(o1); // true 
wm1.delete(o1); 
wm1.has(o1); // false 

powodem jego istnienia jest:

w celu naprawienia wycieku pamięci występującego w wielu zastosowaniach tabel ze słabymi kluczami.

Pozornie emulacja słabych map powoduje wycieki pamięci. Nie znam szczegółów tych wycieków pamięci.

+5

Powodem przecieku pamięci jest to, że aby zaimplementować ją samodzielnie, musisz przechowywać klucze w tablicy, co oznacza, że ​​nigdy nie będą zbierane śmieci, nawet jeśli wszystkie inne odniesienia nie istnieją, więc nie ma możliwości uzyskania dostępu do odpowiedniej wartości tak czy inaczej. –

+1

Myślę, że możesz poprawić tę odpowiedź z punktu widzenia 2015 :) –

15

Słabe odniesienie jest specjalnym obiektem zawierającym obiekt-wskaźnik, ale nie utrzymuje tego obiektu przy życiu.

Jedna aplikacja słabych referencji realizowane są w słabej Maps:

„Doświadczony programista JavaScript zauważy, że ten API mogą być realizowane w JavaScript z dwóch tablic (jeden dla kluczy, jeden dla wartości) współużytkowany przez 4 metody API. Taka implementacja miałaby dwie główne niedogodności. Pierwszy to wyszukiwanie O (n) (n to liczba kluczy na mapie). Drugi to problem wycieku pamięci. Dzięki ręcznie zapisanym mapom tablica kluczy zachowa odniesienia do kluczowych obiektów, zapobiegając ich zbieraniu. W rodzimych WeakMaps, odniesienia do najważniejszych obiektów odbywają się „słabo”, co oznacza, że ​​nie ograniczają one możliwości zbierania śmieci w przypadku nie byłoby żadnego innego odniesienia do obiektu „. Source

(Patrz także mój post gdy ECMAScript Harmony było wydana po raz pierwszy w Firefox ...)

0

WeakMap pozwala używać obiektów jako kluczy. Nie ma żadnej metody poznania długości mapy. Długość zawsze wynosi 1. Klucz nie może być wartością pierwotną

Słowo ostrożnie związane z używaniem obiektu jako klucza, ponieważ wszystkie obiekty są domyślnie w języku JavaScript, należy utworzyć odniesienie do obiektu i użyć go .

Dzieje się tak, ponieważ gdy tworzymy anonimowe obiekty, są one różne.

if ({} !== {}) { console.log('Objects are singletons') }; 
// will print "Objects are singletons" 

Dlatego w następującym scenariuszu, nie możemy oczekiwać, aby uzyskać wartość

var wm = new WeakMap() 
wm.set([1],'testVal'); 
wm.get([1]); // will be undefined 

i następujący fragment będzie działać zgodnie z oczekiwaniami.

var a = [1]; 
wm.set(a, 'testVal'); 
wm.get(a); // will return 'testVal'