Czy usuwanie właściwości obiektu podczas iteracji jest bezpieczne?


101

Czy podczas iteracji po właściwościach obiektu można je bezpiecznie usunąć w pętli for-in?

Na przykład:

for (var key in obj) {
    if (!obj.hasOwnProperty(key)) continue;

    if (shouldDelete(obj[key])) {
        delete obj[key];
    }
}

W wielu innych językach iterowanie po tablicy lub słowniku i usuwanie wewnątrz jest niebezpieczne. Czy w JS jest w porządku?

(Używam środowiska uruchomieniowego Spidermonkey Mozilli).


Rozpocząłem nagrodę za to pytanie, ponieważ uważam, że obecna odpowiedź jest niewystarczająca i nie odpowiada na przedstawione pytanie . Proszę również dołączyć odpowiednie źródło (miejmy nadzieję, ze specyfikacji) i wszelkie istotne „dziwactwa” przeglądarki, jeśli dotyczy.
user2864740

Odpowiedzi:


117

ECMAScript 5.1 norma rozdział 12.6.4 (na pętli for-in) mówi:

Właściwości wyliczanego obiektu można usunąć podczas wyliczania. Jeśli nieruchomość, która nie była jeszcze odwiedzana podczas wyliczania, zostanie usunięta, nie będzie odwiedzana. Jeśli nowe właściwości zostaną dodane do wyliczanego obiektu podczas wyliczania, nie ma gwarancji, że nowo dodane właściwości zostaną odwiedzone w aktywnym wyliczeniu. Nazwa właściwości nie może być odwiedzana więcej niż raz w żadnym wyliczeniu.

Myślę więc, że jest jasne, że kod OP jest legalny i będzie działał zgodnie z oczekiwaniami. Dziwactwa przeglądarki mają wpływ na kolejność iteracji i ogólne instrukcje usuwania, ale nie na to, czy kod OP będzie działał. Generalnie najlepiej jest usunąć tylko bieżącą właściwość w iteracji - usunięcie innych właściwości w obiekcie w nieprzewidywalny sposób spowoduje, że zostaną one uwzględnione (jeśli zostały już odwiedzone) lub nie zostaną uwzględnione w iteracji, chociaż może to lub nie, w zależności od sytuacja.

Zobacz też:

Żadne z nich nie wpływa jednak tak naprawdę na kod OP.


1
Właśnie zauważyłem, że zawarłem ten sam cytat ze standardów, co w innej odpowiedzi, przeprosiny.
TomW

17

Ze specyfikacji Javascript / ECMAScript (konkretnie 12.6.4 Instrukcja for-in ):

Właściwości wyliczanego obiektu można usunąć podczas wyliczania . Jeśli nieruchomość, która nie była jeszcze odwiedzana podczas wyliczania, zostanie usunięta, nie będzie odwiedzana. Jeśli nowe właściwości zostaną dodane do wyliczanego obiektu podczas wyliczania, nie ma gwarancji , że nowo dodane właściwości zostaną odwiedzone w aktywnym wyliczeniu . Nazwa właściwości nie może być odwiedzana więcej niż raz w żadnym wyliczeniu.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.