Czy istnieje sposób w javascript, aby utworzyć „słabe odniesienie” do innego obiektu? Oto strona wiki opisująca, czym jest słabe odniesienie. Oto kolejny artykuł opisujący je w Javie. Czy ktoś może wymyślić sposób na zaimplementowanie tego zachowania w javascript?
javascript
weak-references
Stephen Cagle
źródło
źródło
Odpowiedzi:
W JavaScript nie ma obsługi języków dla slabych odwołań. Możesz tworzyć własne, korzystając z ręcznego liczenia referencji, ale nie jest to szczególnie płynne. Nie można utworzyć obiektu opakowującego proxy, ponieważ w JavaScript obiekty nigdy nie wiedzą, kiedy zostaną zebrane jako elementy bezużyteczne.
Tak więc Twoje „słabe odniesienie” staje się kluczem (np. Liczbą całkowitą) w prostym wyszukiwaniu, z metodą dodawania i usuwania odniesienia, a gdy nie ma już odniesień śledzonych ręcznie, wpis można usunąć, pozostawiając przyszłe wyszukiwania włączone ten klucz, aby zwrócić null.
Nie jest to tak naprawdę słaby punkt, ale może rozwiązać niektóre z tych samych problemów. Zwykle jest to wykonywane w złożonych aplikacjach internetowych, aby zapobiec wyciekowi pamięci z przeglądarek (zwykle IE, zwłaszcza starszych wersji), gdy istnieje pętla odwołań między węzłem DOM lub obsługą zdarzeń a powiązanym z nim obiektem, takim jak zamknięcie. W takich przypadkach pełny schemat liczenia referencji może nawet nie być konieczny.
źródło
Podczas uruchamiania JS na NodeJS możesz rozważyć https://github.com/TooTallNate/node-weak .
źródło
Aktualizacja: wrzesień 2019 r
Na razie nie można używać słabych referencji, ale najprawdopodobniej wkrótce będzie to możliwe, ponieważ WeakRefs w JavaScript to praca w toku. Szczegóły poniżej.
Wniosek
Wniosek jest teraz w etapie 3, co oznacza, że został ukończony specyfikację, a dalsze udoskonalenia będą wymagały informacji zwrotnych od wdrożeń i użytkowników.
WeakRef propozycja obejmuje dwa główne nowe kawałki funkcjonalności:
Przypadków użycia
Podstawowym zastosowaniem słabych odniesienia jest wykonanie bufory lub mapowania posiadających duże przedmioty, gdzie jest pożądane, aby duża obiekt nie jest utrzymywane przy życiu tylko dlatego, że występuje w pamięci podręcznej i mapowania.
Finalizacja to wykonanie kodu w celu oczyszczenia obiektu, który stał się niedostępny dla wykonywania programu. Finalizatory zdefiniowane przez użytkownika umożliwiają kilka nowych przypadków użycia i mogą pomóc w zapobieganiu wyciekom pamięci podczas zarządzania zasobami, o których nie wie moduł odśmiecania pamięci.
Źródło i dalsze czytanie
https://github.com/tc39/proposal-weakrefs
https://v8.dev/features/weak-references
źródło
Prawdziwie słabe odniesienia, nie, jeszcze nie (ale twórcy przeglądarek przyglądają się temu tematowi). Ale oto pomysł, jak symulować słabe odniesienia.
Możesz zbudować pamięć podręczną, przez którą przepuszczasz swoje obiekty. Kiedy obiekt jest przechowywany, pamięć podręczna przechowuje przewidywanie, ile pamięci zajmie obiekt. W przypadku niektórych pozycji, takich jak przechowywanie obrazów, jest to proste do rozwiązania. Dla innych byłoby to trudniejsze.
Kiedy potrzebujesz obiektu, poproś o niego pamięć podręczną. Jeśli pamięć podręczna zawiera obiekt, jest on zwracany. Jeśli go tam nie ma, element jest generowany, przechowywany, a następnie zwracany.
Słabe referencje są symulowane przez elementy usuwające pamięć podręczną, gdy całkowita ilość przewidywanej pamięci osiągnie określony poziom. Przewiduje, które elementy są najmniej używane, na podstawie tego, jak często są one odzyskiwane, ważone według tego, jak dawno zostały wyjęte. Koszt „kalkulacji” można również dodać, jeśli kod, który tworzy element, jest przekazywany do pamięci podręcznej jako zamknięcie. Umożliwiłoby to przechowywanie w pamięci podręcznej przedmiotów, które są bardzo drogie w budowie lub generowaniu.
Algorytm usuwania jest kluczowy, ponieważ jeśli się pomylisz, możesz w końcu usunąć najpopularniejsze elementy. To spowodowałoby straszne wyniki.
Tak długo, jak pamięć podręczna jest jedynym obiektem z trwałymi odniesieniami do przechowywanych obiektów, powyższy system powinien działać całkiem dobrze jako alternatywa dla prawdziwych słabych odniesień.
źródło
Tylko w celach informacyjnych; JavaScript go nie ma, ale ActionScript 3 (który jest również ECMAScript) tak. Sprawdź parametr konstruktora dla Dictionary .
źródło
Użycie mechanizmu buforowania do emulacji słabej referencji, jak sugerowano powyżej JL235 , jest rozsądne. Jeśli słabe referencje istniałyby natywnie, zaobserwowałbyś takie zachowanie:
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
Podczas gdy w przypadku pamięci podręcznej zaobserwowałbyś:
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
Jako posiadacz odniesienia nie powinieneś robić żadnych założeń co do tego, kiedy odwołuje się on do wartości, nie inaczej jest w przypadku użycia pamięci podręcznej
źródło
Wreszcie są tutaj. Jeszcze nie zaimplementowane w przeglądarkach, ale wkrótce będzie.
https://v8.dev/features/weak-references
źródło
EcmaScript 6 (ES Harmony) ma obiekt WeakMap . Obsługa przeglądarek wśród nowoczesnych przeglądarek jest całkiem dobra (obsługują ją ostatnie 3 wersje Firefoksa, Chrome, a nawet nadchodząca wersja IE).
źródło
WeakMap
nie daje słabych odniesień do obiektów - to nie wartości są słabymi odniesieniami w WeakMap, ale klucze . Fakt, że w mapie istnieją słabe odwołania, jest jedynie mechanizmem zapobiegania wyciekom pamięci i nie jest obserwowalny dla użytkownika w inny sposób.weakmap.get(new String('any possible key that has ever existed or ever will exist'))
będzie zawsze byćundefined
. Nie przydatne. Głosowanie przeciw!http://www.jibbering.com/faq/faq_notes/closures.html
ECMAScript używa automatycznego czyszczenia pamięci. Specyfikacja nie definiuje szczegółów, pozostawiając to implementatorom do rozwiązania, a niektóre implementacje są znane z tego, że nadają bardzo niski priorytet swoim operacjom czyszczenia pamięci. Ale ogólna idea jest taka, że jeśli obiekt staje się niemożliwy do odniesienia (przez brak pozostałych odwołań do niego dostępnych dla wykonywania kodu), staje się dostępny do czyszczenia pamięci i zostanie w przyszłości zniszczony, a wszelkie zasoby, które zużywa, zostaną zwolnione i zwrócone do systemu w celu ponownego wykorzystania.
Zwykle miałoby to miejsce w przypadku wyjścia z kontekstu wykonania. Struktura łańcucha zasięgu, obiekt Activation / Variable i wszelkie obiekty utworzone w kontekście wykonywania, w tym obiekty funkcyjne, nie byłyby już dostępne, a zatem stałyby się dostępne do czyszczenia pamięci.
Oznacza to, że nie ma słabych, tylko te, które nie są już dostępne.
źródło