Czy uważasz, że istnieje duża różnica w ... pętlach i pętlach? Jakiego rodzaju „dla” wolisz używać i dlaczego?
Powiedzmy, że mamy tablicę tablic asocjacyjnych:
var myArray = [{'key': 'value'}, {'key': 'value1'}];
Możemy więc iterować:
for (var i = 0; i < myArray.length; i++)
I:
for (var i in myArray)
Nie widzę dużej różnicy. Czy są jakieś problemy z wydajnością?
javascript
andrii
źródło
źródło
myArray.forEach(callback[, thisarg])
.if(myArray.hasOwnProperty(i)){true}
['foo', 'bar', 'baz'].forEach(function(element, index, array){ console.log(element, index, array); });
jest OK, aby używać praktycznie wszędzie oprócz IE8 i jest to zdecydowanie najbardziej elegancka składniafor...of
oświadczenie w ECMAScript 6 , na przykład:for (let i of myArray) console.log(i);
Odpowiedzi:
Wybór powinien opierać się na tym, który idiom jest najlepiej rozumiany.
Tablica jest iterowana przy użyciu:
Obiekt używany jako tablica asocjacyjna jest iterowany przy użyciu:
Jeśli nie masz powodów do zniszczenia ziemi, trzymaj się ustalonego wzorca użytkowania.
źródło
for
, a nie oceniać a. Długość za każdym razem w pętli.i < l
, niei < a
w swoim stanie pętli.Douglas Crockford zaleca w JavaScript: The Good Parts (strona 24), aby uniknąć używania
for in
instrukcji.Jeśli użyjesz
for in
do zapętlenia nazw właściwości w obiekcie, wyniki nie zostaną uporządkowane. Gorzej: Możesz uzyskać nieoczekiwane wyniki; obejmuje elementy odziedziczone z łańcucha prototypów i nazwę metod.Wszystko oprócz właściwości można odfiltrować
.hasOwnProperty
. Ten przykładowy kod robi to, co prawdopodobnie pierwotnie chciałeś:źródło
name
zmienną:for(var name in object)...
, w przeciwnym razie, jeśli kod jest wewnątrz funkcji na przykład,name
zmienna w końcu jest własnością obiektu globalnego (przypisanie do identyfikatora nierejestrowanej to robi), również w nowej ECMAScript 5 Tryb ścisły, ten kod rzuci aReferenceError
.FYI - Użytkownicy jQuery
each(callback)
Metoda jQueryfor( ; ; )
domyślnie używa pętli i będzie używanafor( in )
tylko, jeśli długość wynosiundefined
.Dlatego powiedziałbym, że korzystanie z tej funkcji jest bezpieczne.
Przykład :
Minusem korzystania z tego jest to, że jeśli robisz logikę inną niż interfejs użytkownika, twoje funkcje będą mniej przenośne dla innych platform. The
each()
Funkcja jest prawdopodobnie najlepiej zarezerwowane do użytku z selektorów jQuery ifor( ; ; )
może być wskazane inaczej.źródło
różnice w wydajności zależą od rodzaju używanej pętli i przeglądarki.
Na przykład:
jest prawie dwa razy szybszy w niektórych przeglądarkach niż:
Jednakże, chyba że twoje tablice są OGROMNE lub nie zapętlasz ich ciągle, wszystkie są wystarczająco szybkie. Poważnie wątpię, że zapętlenie tablicy jest wąskim gardłem w twoim projekcie (lub w każdym innym projekcie w tym zakresie)
źródło
for(var i = myArray.length; i--;)
Zauważ, że natywna metoda Array.forEach jest obecnie szeroko obsługiwana .
źródło
Zaktualizowana odpowiedź dla bieżącej wersji wszystkich głównych przeglądarek 2012 - Chrome, Firefox, IE9, Safari i Opera obsługują natywną tablicę ES5. Dla każdego.
O ile nie masz żadnego powodu, aby natywnie obsługiwać IE8 (pamiętając, że użytkownicy mogą zapewnić ES5-shim lub ramkę Chrome, co zapewni odpowiednie środowisko JS), czystsze jest użycie właściwej składni języka:
Pełna dokumentacja dla array.forEach () znajduje się w MDN.
źródło
Obie nie są takie same, gdy tablica jest rzadka.
źródło
Użycie forEach do pominięcia łańcucha prototypów
Wystarczy szybki dodatek do powyższej odpowiedzi @ nailer , użycie forEach z Object.keys oznacza, że możesz uniknąć iteracji w łańcuchu prototypów bez konieczności używania hasOwnProperty.
źródło
Druga opinia, że powinieneś wybrać metodę iteracji zgodnie z twoimi potrzebami. Proponuję ci rzeczywiście nie do historii pętli poprzez rodem
Array
zfor in
konstrukcji. Jest znacznie wolniejszy i , jak wskazał przed chwilą Chase Seibert, nie jest zgodny z frameworkiem Prototype.Jest doskonały punkt odniesienia dla różnych stylów zapętlenia, na który absolutnie powinieneś się przyjrzeć, jeśli pracujesz z JavaScript . Nie rób wczesnych optymalizacji, ale powinieneś trzymać to gdzieś z tyłu głowy.
Użyłbym,
for in
aby uzyskać wszystkie właściwości obiektu, co jest szczególnie przydatne podczas debugowania twoich skryptów. Na przykład, lubię mieć tę linię pod ręką, kiedy eksploruję nieznany obiekt:Zrzuca zawartość całego obiektu (wraz z ciałami metod) do mojego dziennika Firebug. Bardzo przydatny.
źródło
oto coś, co zrobiłem.
tak byś go użył to
zadziała na tablicach i obiektach (takich jak lista elementów HTML)
Właśnie to zrobiłem, więc jestem otwarty na sugestie :)
źródło
Używałbym różnych metod opartych na tym, jak chciałem odwoływać się do przedmiotów.
Użyj foreach, jeśli chcesz tylko bieżący element.
Użyj, jeśli potrzebujesz indeksatora do porównań względnych. (Tj. Jak to porównać do poprzedniego / następnego elementu?)
Nigdy nie zauważyłem różnicy w wydajności. Zaczęłam się martwić, dopóki nie będę mieć problemu z wydajnością.
źródło
Za pomocą for (var i w myArray) możesz także zapętlać obiekty, ja będę zawierał nazwę klucza i możesz uzyskać dostęp do właściwości za pośrednictwem myArray [i] . Dodatkowo, wszelkie metody zostaną dodane do obiektu zostaną uwzględnione w pętli, zbyt, to znaczy, jeśli użyć dowolnego ramy zewnętrznej jak jQuery lub prototyp, lub jeśli dodać metod do prototypów obiektu bezpośrednio, w pewnym momencie i będzie wskazywać na te metody.
źródło
Uważaj!
Jeśli masz kilka znaczników skryptu i szukasz na przykład informacji w atrybutach znacznika, musisz użyć właściwości .length z pętlą for, ponieważ nie jest to prosta tablica, ale obiekt HTMLCollection.
https://developer.mozilla.org/en/DOM/HTMLCollection
Jeśli użyjesz instrukcji foreach dla (var i na twojej liście), zwróci ona właściwości i metody HTMLCollection w większości przeglądarek!
Nawet jeśli getElementsByTagName powinien zwrócić NodeList, większość przeglądarek zwraca HTMLCollection: https://developer.mozilla.org/en/DOM/document.getElementsByTagName
źródło
Bo w pętlach na tablicach nie jest kompatybilny z Prototype. Jeśli uważasz, że w przyszłości będziesz musiał użyć tej biblioteki, warto trzymać się pętli.
http://www.prototypejs.org/api/array
źródło
Widziałem problemy z „dla każdego” przy użyciu obiektów, prototypów i tablic
rozumiem, że dla każdego dotyczy właściwości obiektów, a NIE tablic
źródło
Jeśli naprawdę chcesz przyspieszyć swój kod, co powiesz na to?
jest to rodzaj logiki while w instrukcji for i jest mniej zbędny. Również Firefox ma Array.forEach i Array.filter
źródło
Krótszy i najlepszy kod według jsperf to
źródło
Użyj pętli Array (). ForEach, aby skorzystać z równoległości
źródło
Array.prototype.forEach
nie będzie wykonywać wielu wywołań zwrotnych równolegle.dla (;;) jest dla tablic : [20,55,33]
for..in jest dla Objects : {x: 20, y: 55: z: 33}
źródło
Bądź ostrożny!!! Używam Chrome 22.0 w Mac OS i mam problem z każdą składnią.
Nie wiem, czy jest to problem z przeglądarką, problem z javascript lub jakiś błąd w kodzie, ale jest to BARDZO dziwne. Na zewnątrz obiektu działa idealnie.
źródło
Istnieje ważna różnica między nimi. Funkcja for-in iteruje właściwości obiektu, więc gdy przypadek jest tablicą, będzie iterował nie tylko swoje elementy, ale także funkcję „usuń”, którą posiada.
Możesz użyć for-in z
if(myArray.hasOwnProperty(i))
. Mimo to, podczas iteracji po tablicach zawsze wolę tego unikać i po prostu używam instrukcji for (;;).źródło
Chociaż oba są bardzo do siebie podobne, istnieje niewielka różnica:
w tym przypadku wynikiem jest:
STANDARD DLA PĘTLI:
Tablica [0] = A
Tablica [1] = B
Tablica [2] = C
podczas gdy w tym przypadku wynikiem jest:
PĘTLA DOSTĘPNA:
Tablica [1] = B
Tablica [2] = C
Tablica [10] = D
Tablica [ABC] = 123
źródło
Instrukcja for in pozwala na przeglądanie nazw wszystkich właściwości obiektu. Niestety, zapętla również wszystkie elementy odziedziczone przez łańcuch prototypów. Ma to zły efekt uboczny polegający na udostępnianiu funkcji metod, gdy zainteresowanie dotyczy elementów danych.
źródło