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 sjest inna dla każdej iteracji, ale nadal może być zadeklarowana constw 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; lengthtakiej 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 undefinedtam 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 procesundefineds 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 lengthrazy, a zmienna sterująca pętli jest ustawiana undefinedna 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#forEachmetody 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, .forEachwywoł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 undefinedjako argument. Jeśli jest to w jaki sposób chcesz obsługiwać macierze rzadkie, .forEachmoż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 lengthrazy, z szestawem do undefinedwszelkich brakujących elementów, podobnie jak for.. of. Jeśli zamiast tego chcesz obsługiwać tylko faktycznie obecne elementy rzadkiej tablicy, .forEachmożesz dodać prosty intest 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.lengthwyraż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... ofnie daje indeksu powiązanego z każdym obiektem, ale dopóki obiekt, który iterujesz, jest w rzeczywistości Array( for.. ofdział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... inskł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ą lengthwł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.