Tak, zakładając, że twoja implementacja zawiera for
...of
funkcję wprowadzoną w ECMAScript 2015 (wydanie „Harmony”)… co jest całkiem bezpiecznym założeniem w dzisiejszych czasach.
Działa to tak:
// REQUIRES ECMASCRIPT 2015+
var s, myStringArray = ["Hello", "World"];
for (s of myStringArray) {
// ... do something with s ...
}
Albo jeszcze lepiej, ponieważ ECMAScript 2015 zapewnia również zmienne o zasięgu blokowym:
// REQUIRES ECMASCRIPT 2015+
const myStringArray = ["Hello", "World"];
for (const s of myStringArray) {
// ... do something with s ...
}
// s is no longer defined here
(Zmienna s
jest inna dla każdej iteracji, ale nadal może być zadeklarowana const
w ciele pętli, o ile nie jest tam modyfikowana).
Uwaga na rzadkie tablice: tablica w JavaScript może tak naprawdę nie przechowywać tylu elementów, ile zgłasza length
; podana liczba jest po prostu o jeden większa niż najwyższy wskaźnik, pod którym przechowywana jest wartość. Jeśli tablica zawiera mniej elementów niż wskazuje jej długość, mówi się, że jest rzadka . Na przykład, całkowicie uzasadnione jest posiadanie tablicy z elementami tylko o indeksach 3, 12 i 247; length
takiej tablicy jest zgłaszane jako 248, choć w rzeczywistości jest tylko 3 przechowywania wartości. Jeśli spróbujesz uzyskać dostęp do elementu w dowolnym innym indeksie, tablica będzie miała undefined
tam wartość. Kiedy więc chcesz „zapętlić” tablicę, musisz odpowiedzieć na pytanie: czy chcesz zapętlić cały zakres wskazany przez jego długość i procesundefined
s dla brakujących elementów, czy chcesz przetwarzać tylko te elementy, które faktycznie są obecne? Istnieje wiele aplikacji dla obu podejść; to zależy tylko od tego, do czego używasz tablicy.
Jeśli wykonasz iterację po tablicy za pomocą for
... of
, treść pętli jest wykonywana length
razy, a zmienna sterująca pętli jest ustawiana undefined
na dowolne elementy, które faktycznie nie występują w tablicy. W zależności od szczegółów kodu „zrób coś z” takie zachowanie może być tym, czego chcesz, ale jeśli nie, powinieneś zastosować inne podejście.
Oczywiście, niektórzy deweloperzy nie mają wyboru, aby użyć innego podejścia tak, ponieważ z jakiegoś powodu są one kierowane na wersję JavaScript, który nie obsługuje jeszcze for
... of
.
Tak długo, jak implementacja JavaScript jest zgodna z poprzednią edycją specyfikacji ECMAScript (która wyklucza na przykład wersje Internet Explorera przed 9), możesz użyć Array#forEach
metody iteratora zamiast pętli. W takim przypadku przekazujesz funkcję, która ma zostać wywołana dla każdego elementu w tablicy:
var myStringArray = [ "Hello", "World" ];
myStringArray.forEach( function(s) {
// ... do something with s ...
} );
W przeciwieństwie do for
... of
, .forEach
wywołuje funkcję tylko dla elementów, które faktycznie są obecne w tablicy. Jeśli przejdzie przez naszą hipotetyczną tablicę z trzema elementami i długością 248, wywoła funkcję tylko trzy razy, a nie 248 razy. Rozróżnia także brakujące elementy od elementów, które są ustawione undefined
; w drugim przypadku nadal wywoła funkcję, przekazując undefined
jako argument. Jeśli jest to w jaki sposób chcesz obsługiwać macierze rzadkie, .forEach
może być droga, nawet jeśli obsługuje tłumacza for
... of
.
Ostatnią opcją, która działa we wszystkich wersjach JavaScript, jest wyraźna pętla zliczania . Po prostu liczysz od 0 do jednego mniej niż długość i używasz licznika jako indeksu. Podstawowa pętla wygląda następująco:
var i, s, myStringArray = [ "Hello", "World" ], len = myStringArray.length;
for (i=0; i<len; ++i) {
s = myStringArray[i];
// ... do something with s ...
}
Zaletą tego podejścia jest to, że możesz wybrać sposób obsługi rzadkich tablic; Powyższy kod będzie działał ciało pełne pętli length
razy, z s
zestawem do undefined
wszelkich brakujących elementów, podobnie jak for
.. of
. Jeśli zamiast tego chcesz obsługiwać tylko faktycznie obecne elementy rzadkiej tablicy, .forEach
możesz dodać prosty in
test do indeksu:
var i, s, myStringArray = [ "Hello", "World" ], len = myStringArray.length;
for (i=0; i<len; ++i) {
if (i in myStringArray) {
s = myStringArray[i];
// ... do something with s ...
}
}
Przypisanie wartości długości zmiennej lokalnej (w przeciwieństwie do włączenia pełnego myStringArray.length
wyrażenia w warstwie pętli) może mieć znaczącą różnicę w wydajności, ponieważ pomija wyszukiwanie właściwości za każdym razem; przy użyciu Rhino na moim komputerze, przyspieszenie wynosi 43%.
Możesz zobaczyć buforowanie długości wykonane w klauzuli inicjalizacji pętli, jak poniżej:
var i, len, myStringArray = [ "Hello", "World" ];
for (len = myStringArray.length, i=0; i<len; ++i) {
Wyraźna pętla zliczania oznacza również, że masz dostęp do indeksu każdej wartości, jeśli chcesz. Indeks jest także przekazywany jako dodatkowy parametr do funkcji, którą przekazujesz forEach
, więc możesz uzyskać do niego dostęp również w ten sposób:
myStringArray.forEach( function(s, i) {
// ... do something with s and i ...
});
for
... of
nie daje indeksu powiązanego z każdym obiektem, ale dopóki obiekt, który iterujesz, jest w rzeczywistości Array
( for
.. of
działa dla innych typów iterowalnych, które mogą nie mieć tej metody), możesz użyć tablicy Metoda #entries , aby zmienić ją na tablicę par [indeks, pozycja], a następnie iterować:
for (const [i, s] of myStringArray.entries()) {
// ... do something with s and i ...
}
for
... in
składnia wspomniano przez innych jest dla zapętlenie nad właściwości obiektu; ponieważ tablica w JavaScript jest tylko obiektem z numerycznymi nazwami właściwości (i automatycznie aktualizowaną length
właściwością), teoretycznie można za jej pomocą łączyć się z tablicą. Problem polega jednak na tym, że nie ogranicza się on do liczbowych wartości właściwości (pamiętaj, że nawet metody są w rzeczywistości właściwościami, których wartością jest zamknięcie), ani nie ma gwarancji, że będą iterować w stosunku do tych w kolejności numerycznej. Dlatego składnia for
... niein
powinna być używana do zapętlania tablic.