Za pomocą tablicy JavaScript mogę zresetować ją do pustego stanu za pomocą jednego przypisania:
array.length = 0;
To sprawia, że tablica „wydaje się” pusta i gotowa do ponownego użycia, a o ile rozumiem, jest to pojedyncza „operacja” - to znaczy stały czas.
Czy istnieje podobny sposób na wyczyszczenie obiektu JS? Wiem, że mogę iterować jego pola, usuwając je:
for (var prop in obj) { if (obj.hasOwnProperty(prop)) { delete obj[prop]; } }
ale ma to złożoność liniową.
Mogę też po prostu wyrzucić obiekt i stworzyć nowy:
obj = {};
Ale „rozwiązłe” tworzenie nowych obiektów prowadzi do problemów z Garbage Collection w IE6. ( Jak opisano tutaj )
javascript
performance
levik
źródło
źródło
for (var prop in obj)
Odpowiedzi:
Myślę, że krótka odpowiedź na twoje pytanie brzmi: nie (możesz po prostu stworzyć nowy obiekt).
W tym przykładzie uważam, że ustawienie długości na 0 nadal pozostawia wszystkie elementy do czyszczenia pamięci.
Możesz dodać to do Object.prototype, jeśli jest to coś, czego często używasz. Tak, jest to liniowe pod względem złożoności, ale wszystko, co później nie usunie elementów bezużytecznych, będzie.
To najlepsze rozwiązanie. Wiem, że to nie jest związane z twoim pytaniem - ale jak długo musimy kontynuować obsługę IE6? Istnieje wiele kampanii mających na celu zaprzestanie korzystania z niego.
Zapraszam do poprawiania mnie, jeśli powyżej jest coś nieprawidłowego.
źródło
Cóż, ryzykując, że wszystko będzie zbyt łatwe ...
... wydawałby się całkiem skuteczny w czyszczeniu obiektu w jednej linii kodu z minimalną ilością przerażających nawiasów. Wszyscy członkowie zostaną naprawdę usunięci, a nie pozostawieni jako śmieci.
Oczywiście, jeśli chcesz usunąć sam obiekt, nadal będziesz musiał wykonać w tym celu oddzielną metodę delete ().
źródło
hasOwnProperty
w tej pętli. Przeczytałem dokumentację, ale nadal próbuję się zastanowić, jakie, jeśli w ogóle, są zagrożenia, jeśli pominiemyhasOwnProperty()
czek?ES5
Rozwiązanie ES5 może być:
ES6
A rozwiązaniem ES6 może być:
Występ
Niezależnie od specyfikacji najszybszymi rozwiązaniami będą na ogół:
Powodem, dla którego
for..in
powinno być wykonywane tylko na płytkim lub prostym obiekcie, jest to, że przechodzi on przez właściwości, które są prototypowo dziedziczone, a nie tylko przez własne właściwości, które można usunąć. W przypadku, gdy nie wiadomo na pewno, że obiekt jest jasny i właściwości są przeliczalne,for
zeObject.getOwnPropertyNames
jest lepszym wyborem.źródło
Możesz tego spróbować. Poniższa funkcja ustawia wszystkie wartości właściwości obiektu na niezdefiniowane. Działa również z obiektami zagnieżdżonymi.
źródło
Podsumowując swoje pytanie: chcesz uniknąć, w miarę możliwości, problemów z błędem IE6 GC. Ten błąd ma dwie przyczyny:
Wydaje się, że rozwiązaniem przyczyny 1 jest: utrzymanie małej liczby przydziałów; przypisuj nowe obiekty i ciągi tak mało, jak to możliwe.
Wydaje się, że rozwiązaniem przyczyny 2 jest: ograniczenie liczby „żywych” obiektów; usuwaj ciągi i obiekty, gdy nie będziesz ich już potrzebować, i twórz je od nowa, gdy zajdzie taka potrzeba.
Do pewnego stopnia rozwiązania te są sprzeczne: utrzymanie małej liczby obiektów w pamięci pociągnie za sobą więcej alokacji i cofnięć. I odwrotnie, ciągłe ponowne wykorzystywanie tych samych obiektów może oznaczać przechowywanie w pamięci większej liczby obiektów, niż jest to absolutnie konieczne.
A teraz pytanie. Niezależnie od tego, czy zresetujesz obiekt, tworząc nowy, czy usuwając wszystkie jego właściwości: będzie to zależeć od tego, co chcesz z nim później zrobić.
Prawdopodobnie będziesz chciał przypisać do niego nowe właściwości:
Nie ma szybkiego i łatwego w użyciu sposobu na wyczyszczenie obiektu JScript do ponownego użycia, tak jakby był to nowy obiekt - bez tworzenia nowego. Co oznacza, że krótka odpowiedź na twoje pytanie brzmi „nie”, jak mówi jthompson.
źródło
Coś nowego do przemyślenia w oczekiwaniu na Object.observe w ES7 i ogólnie z wiązaniem danych. Rozważać:
W tej sytuacji nr 2 może być najlepszym wyborem.
źródło
obj = {}
spowoduje, że framework nie będzie świadomy jakichkolwiek dalszych zmian w obiekcie, dlatego twoje szablony nie będą poprawnie renderowane. Jednak opcja nr 2 będzie działać poprawnie.Możesz usunąć właściwości, ale nie usuwaj zmiennych.
delete abc;
jest nieprawidłowy w ES5 (i wyrzuca z użyciem ścisłego).Możesz przypisać go do wartości null, aby ustawić go do usunięcia w GC (nie będzie, jeśli masz inne odniesienia do właściwości)
Ustawienie
length
właściwości obiektu niczego nie zmienia. (tylko, cóż, ustawia właściwość)źródło
length
na 0 w tablicy (która jest określonym typem obiektu - jeśli mi nie wierzysz, spróbuj uruchomićtypeof []
), nie tylko ustawi właściwość, w rzeczywistości wyczyści zawartość tablicy . Zobacz stackoverflow.com/questions/1232040/…window.abc
ponieważ w tym przypadku jest to rekwizyt.To mnie niepokoiło przez wieki, więc oto moja wersja, ponieważ nie chciałem pustego obiektu, chciałem mieć taki, który ma wszystkie właściwości, ale został zresetowany do jakiejś domyślnej wartości. Coś jak nowa instancja klasy.
źródło