For-each nad tablicą w JavaScript?

Jak mogę zapętlić wszystkie wpisy w tablicy używając JavaScript?

Myślałem, że to coś takiego:

forEach(instance in theArray)

Gdzie theArray jest moją tablicą, ale wydaje się to być błędne.

Author: T.J. Crowder, 2012-02-17

28 answers

TL; DR

  • nie używaj for-in chyba, że używasz go z zabezpieczeniami lub przynajmniej wiesz, dlaczego może cię ugryźć.
  • Twoje najlepsze zakłady to zazwyczaj

    • a for-of pętla (tylko ES2015+),
    • Array#forEach (spec | MDN) (w 1996 roku został wybrany do Izby Gmin.]}
    • prosta, staromodna pętlafor,
    • lub for-in z zabezpieczenia.

Ale jest wiele więcej do zbadania, Czytaj dalej...


JavaScript ma potężną semantykę do zapętlania tablic i obiektów podobnych do tablic. Podzieliłem odpowiedź na dwie części: opcje dla oryginalnych tablic i opcje dla rzeczy, które są tylko tablicami - , takich jak, takie jak obiekt arguments, inne iterable objects (ES2015+), Kolekcje DOM i tak dalej.

Szybko zauważę, że można używać ES2015 opcje teraz , nawet w silnikach ES5, przez transpiling ES2015 do ES5. Szukaj "ES2015 transpiling" / "ES6 transpiling", aby uzyskać więcej informacji...

Dobra, spójrzmy na nasze opcje:

Dla Rzeczywistych Tablic

Masz trzy opcje w ECMAScript 5 ("ES5"), wersji najbardziej obecnie obsługiwanej, i dwie dodatkowe dodane w ECMAScript 2015 ("ES2015", "ES6"):

  1. użycie forEach i pokrewne (ES5+)
  2. użyj prostej for pętli
  3. użycie for-in poprawnie
  4. W tym celu należy użyć iteratora (ES2015+).]} W tym celu należy użyć iteratora w sposób jawny (ES2015+).]}

Szczegóły:

1. Użycie forEach i pokrewne

W dowolnym nowoczesnym środowisku (a więc nie IE8), gdzie masz dostęp do Array funkcji dodanych przez ES5 (bezpośrednio lub za pomocą polyfills), możesz użyć forEach (spec | MDN):

var a = ["a", "b", "c"];
a.forEach(function(entry) {
    console.log(entry);
});

forEach akceptuje funkcję wywołania zwrotnego i, opcjonalnie, wartość do użycia jako this podczas wywoływania tego wywołania zwrotnego (nie używana powyżej). Wywołanie zwrotne jest wywoływane dla każdego wpisu w tablicy, w kolejności, pomijając nieistniejące wpisy w rzadkich tablicach. Chociaż użyłem tylko jednego argumentu powyżej, wywołanie zwrotne jest wywoływane z trzema: wartością każdego wpisu, indeksem tego wpisu i odniesieniem do tablicy, którą iterujesz (w przypadku, gdy twoja funkcja jeszcze nie ma to poręczne).

O ile nie obsługujesz przestarzałych przeglądarek, takich jak IE8 (który netapps pokazuje nieco ponad 4% udziału w rynku od tego napisania we wrześniu 2016), możesz z przyjemnością używać forEach na stronie ogólnego przeznaczenia bez podkładki. Jeśli potrzebujesz obsługiwać przestarzałe przeglądarki, shimming/polyfilling forEach jest łatwo zrobić (wyszukaj "ES5 shim" dla kilku opcji).

forEach mA tę zaletę, że nie musisz deklarować zmiennych indeksujących i wartości w zakresie zawierającym, jako są one dostarczane jako argumenty do funkcji iteracji i tak ładnie ograniczone do tej iteracji.

Jeśli martwisz się o koszt wywołania funkcji dla każdego wpisu tablicy, nie bądź; details.

Dodatkowo, forEach jest funkcją "loop through them all", ale ES5 zdefiniował kilka innych przydatnych funkcji "work your way through the array and do things", w tym:

  • every (przestaje zapętlać za pierwszym razem wywołanie zwrotne zwraca false lub coś false)
  • some (po pierwsze, gdy wywołanie zwrotne powraca true lub coś prawdziwego)
  • filter (tworzy nową tablicę zawierającą elementy, w których funkcja filtra zwraca true i pomija te, w których zwraca false)
  • map (tworzy nową tablicę z wartości zwracanych przez wywołanie zwrotne)
  • reduce (buduje wartość poprzez wielokrotne wywołanie wywołania zwrotnego, przekazywanie poprzednich wartości; szczegółowe informacje można znaleźć w specyfikacji; przydatne do sumowania zawartości tablicy i wielu innych rzeczy)
  • reduceRight (podobnie jak reduce, ale działa w kolejności malejącej, a nie rosnącej)

2. Użyj prostej pętli for

Czasami stare sposoby są najlepsze:

var index;
var a = ["a", "b", "c"];
for (index = 0; index < a.length; ++index) {
    console.log(a[index]);
}

Jeśli długość tablicy nie zmieni się podczas pętli i jest w kodzie wrażliwym na wydajność( mało prawdopodobne), nieco bardziej skomplikowana wersja tiny trochę szybciej:

var index, len;
var a = ["a", "b", "c"];
for (index = 0, len = a.length; index < len; ++index) {
    console.log(a[index]);
}

I/lub liczenie wstecz:

var index;
var a = ["a", "b", "c"];
for (index = a.length - 1; index >= 0; --index) {
    console.log(a[index]);
}

Ale z nowoczesnymi silnikami JavaScript, rzadko trzeba wycisnąć ten ostatni kawałek soku.

W ES2015 i nowszych możesz ustawić zmienne indeks i wartość lokalnie w pętlifor:

let a = ["a", "b", "c"];
for (let index = 0; index < a.length; ++index) {
    let value = a[index];
}
//console.log(index); // Would cause "ReferenceError: index is not defined"
//console.log(value); // Would cause "ReferenceError: value is not defined"

I kiedy to zrobisz, nie tylko value, ale także index jest odtwarzane dla każdej iteracji pętli, co oznacza zamknięcia utworzone w ciele pętli zachowują odniesienie do index (i value) utworzonych dla tej konkretnej iteracji:

let divs = document.querySelectorAll("div");
for (let index = 0; index < divs.length; ++index) {
    divs[index].addEventListener('click', e => {
        alert("Index is: " + index);
    });
}

Jeśli masz pięć div, dostaniesz "Index is: 0", jeśli klikniesz pierwszy i "Index is: 4", Jeśli klikniesz ostatni. To działa Nie jeśli używasz var zamiast let.

3. Użycie for-in poprawnie

Ludzie każą ci używać for-in, ale to nie jest to, co {21]} jest dla. for-in pętle poprzez wylicz właściwości obiektu , a nie indeksy tablicy. kolejność nie jest gwarantowana , nawet w ES2015 (ES6). ES2015 definiuje kolejność właściwości obiektu (poprzez [[OwnPropertyKeys]], [[Enumerate]], i rzeczy, które ich używają jak Object.getOwnPropertyKeys), ale to nie definiuje, że for-in będzie postępować zgodnie z tą kolejnością. (Szczegóły w tej drugiej odpowiedzi .)

Mimo to, to może być przydatne, szczególnie na sparse tablice, jeśli używasz odpowiednich zabezpieczeń:

// `a` is a sparse array
var key;
var a = [];
a[0] = "a";
a[10] = "b";
a[10000] = "c";
for (key in a) {
    if (a.hasOwnProperty(key)  &&        // These are explained
        /^0$|^[1-9]\d*$/.test(key) &&    // and then hidden
        key <= 4294967294                // away below
        ) {
        console.log(a[key]);
    }
}

Zwróć uwagę na dwie kontrole:

  1. Obiekt posiada własną właściwość o tej nazwie (nie dziedziczy po swoim prototypie), oraz

  2. Że klucz jest ciągiem liczbowym base - 10 w postaci zwykłego ciągu znaków, a jego wartość wynosi w specyfikacji . Pozostałe liczby (liczby niezliczone, liczby ujemne, liczby większe niż 2^32 - 2) nie są indeksami tablicowymi. Powodem jest 2^32 - 2 czy to sprawia, że największa wartość indeksu jest niższa niż 2^32 - 1, jest to maksymalna wartość, jaką może mieć tablica length. (Np. długość tablicy mieści się w 32-bitowej niepodpisanej liczbie całkowitej.) (rekwizyty dla Robga za wskazanie w komentarzu na moim blogu że mój poprzedni test nie był całkiem racja.)

Jest to malutki narzut na iterację pętli na większości tablic, ale jeśli masz rzadką tablicę, może to być bardziej efektywny sposób pętli, ponieważ pętle są tylko dla wpisów, które rzeczywiście istnieją. Np. dla powyższej tablicy pętlujemy łącznie trzy razy (dla kluczy "0", "10", i "10000" - pamiętaj, że to sznurki), a nie 10 001 razy.

Teraz nie będziesz chciał tego pisać za każdym razem, więc możesz umieścić to w swoim zestaw narzędzi:

function arrayHasOwnIndex(array, prop) {
    return array.hasOwnProperty(prop) && /^0$|^[1-9]\d*$/.test(prop) && prop <= 4294967294; // 2^32 - 2
}

I wtedy użylibyśmy tego tak:

for (key in a) {
    if (arrayHasOwnIndex(a, key)) {
        console.log(a[key]);
    }
}
Jeśli nie chcesz, aby twój test był wystarczająco dobry dla większości przypadków, możesz go użyć, ale mimo, że jest blisko, nie jest do końca poprawny.]}
for (key in a) {
    // "Good enough" for most cases
    if (String(parseInt(key, 10)) === key && a.hasOwnProperty(key)) {
        console.log(a[key]);
    }
}

4. W tym celu należy użyć iteratora.]}

ES2015 dodaje Iteratory do JavaScript. Najprostszym sposobem użycia iteratorów jest nowa Instrukcja for-of. Wygląda na to, że to:

var val;
var a = ["a", "b", "c"];
for (val of a) {
    console.log(val);
}

Wyjście:

a
b
c

Pod pokrywą, który otrzymuje iterator z tablicy i pętli przez nią, pobierając z niej wartości. Nie ma problemu, jaki ma użycie for-in, ponieważ używa iteratora zdefiniowanego przez obiekt (tablicę), a tablice definiują, że ich Iteratory są iteracyjne poprzez ich wpisy (Nie ich właściwości). W przeciwieństwie do for-in w ES5, kolejność odwiedzania wpisów jest kolejnością liczbową ich indeksy.

5. Użycie iteratora jawnie (ES2015+)

Czasami warto użyć iteratora jawnie . To też możesz zrobić, chociaż jest o wiele bardziej clunkierne niż for-of. Wygląda to tak:

var a = ["a", "b", "c"];
var it = a.values();
var entry;
while (!(entry = it.next()).done) {
    console.log(entry.value);
}

Iterator jest obiektem pasującym do definicji iteratora w specyfikacji. Jej metoda next zwraca nowy obiekt wynikowy za każdym razem, gdy go wywołasz. Obiekt wynikowy ma właściwość done, mówiącą nam, czy jest zrobione, oraz właściwość value z wartością dla tej iteracji. (done jest opcjonalne, jeśli byłoby false, value jest opcjonalne, jeśli byłoby undefined.)

W zależności od iteratora znaczenie tablic może się różnić; tablice obsługują (przynajmniej) trzy funkcje zwracające Iteratory:
  • values(): to jest ten, którego użyłem powyżej. Zwraca iterator, gdzie każdy value jest wpisem tablicy dla tej iteracji ("a", "b", i "c" w przykładzie wcześniejszym).
  • keys(): zwraca iterator, w którym każdy value jest kluczem do tej iteracji(więc dla naszego a powyżej, to będzie "0", następnie "1", następnie "2").
  • entries(): zwraca iterator, gdzie każdy value jest tablicą w postaci [key, value] dla tej iteracji.

Dla Obiektów Podobnych Do Tablicy

Oprócz prawdziwych tablic, istnieją również podobne do tablicy obiekty, które mają właściwość length oraz właściwości o nazwach numerycznych: NodeList instancje, obiekt arguments, itd. Jak możemy przejrzeć ich zawartość?

Użyj dowolnej z powyższych opcji dla tablic

[139]}przynajmniej niektóre, a być może Większość lub nawet wszystkie, podejścia do tablicy powyżej często stosują się równie dobrze do obiektów podobnych do tablicy: {142]}
  1. Use forEach and related (ES5+)

    Różne funkcje na Array.prototype są "celowo ogólne" i mogą być zwykle używane na obiektach podobnych do tablicy poprzez Function#call lub Function#apply. (Patrz zastrzeżenie dla obiektów hosta na końcu tej odpowiedzi, ale to rzadki problem.)

    Załóżmy, że chcesz użyć forEach na Node'S childNodes właściwość. Zrobiłbyś to:

    Array.prototype.forEach.call(node.childNodes, function(child) {
        // Do something with `child`
    });
    

    Jeśli zamierzasz robić to często, możesz chcieć pobrać kopię referencji funkcji do zmiennej w celu ponownego użycia, np.:]}

    // (This is all presumably in some scoping function)
    var forEach = Array.prototype.forEach;
    
    // Then later...
    forEach.call(node.childNodes, function(child) {
        // Do something with `child`
    });
    
  2. Użyj prostej pętli for

    Oczywiście, prosta for pętla ma zastosowanie do tablicy obiektów.

  3. Użycie for-in prawidłowo

    for-in z tymi samymi zabezpieczeniami jak w przypadku tablicy powinny działać również z obiektami podobnymi do tablicy; może mieć zastosowanie zastrzeżenie dla obiektów dostarczanych przez host na #1 powyżej.

  4. Use for-of (use an iterator implicite) (ES2015+)

    for-of użyje iteratora dostarczonego przez obiekt( jeśli istnieje); będziemy musieli zobaczyć, jak to działa z różnymi obiektami typu array, szczególnie te, które są dostarczane przez gospodarzy. Na przykład Specyfikacja NodeList z querySelectorAll została zaktualizowana, aby wspierać iterację. Spec dla HTMLCollection z getElementsByTagName nie było.

  5. Jawnie używaj iteratora (ES2015+)

    Patrz #4, musimy zobaczyć, jak Iteratory się rozegrają.

Tworzenie prawdziwej tablicy

Innym razem możesz chcieć przekonwertować obiekt podobny do tablicy na tablicę rzeczywistą. To zaskakujące. łatwe:

  1. Użyj slice metoda tablic

    Możemy użyć metody slice tablic, która podobnie jak inne metody wymienione powyżej jest "celowo ogólna" i dlatego może być używana z obiektami podobnymi do tablic, jak poniżej:

    var trueArray = Array.prototype.slice.call(arrayLikeObject);
    

    Więc na przykład, jeśli chcemy przekonwertować NodeList do tablicy prawdziwej, możemy to zrobić:

    var divs = Array.prototype.slice.call(document.querySelectorAll("div"));
    

    Zobacz Zastrzeżenie dla obiektów dostarczanych przez host poniżej. W szczególności Uwaga że to się nie powiedzie w IE8 i wcześniejszych, co nie pozwala używać obiektów dostarczanych przez host jako this W ten sposób.

  2. Użyj składni spread (...)

    Możliwe jest również użycie składni spreadowej ES2015 z silnikami JavaScript, które obsługują tę funkcję:
    var trueArray = [...iterableObject];
    

    Więc na przykład, jeśli chcemy przekonwertować NodeList do tablicy true, ze składnią spread staje się to całkiem zwięzłość:

    var divs = [...document.querySelectorAll("div")];
    
  3. Użycie Array.from (spec) | (MDN)

    Array.from (ES2015+, ale łatwo polyfilled) tworzy tablicę z obiektu podobnego do tablicy, opcjonalnie przekazując najpierw wpisy przez funkcję mapowania. Więc:

    var divs = Array.from(document.querySelectorAll("div"));
    

    Lub jeśli chcesz uzyskać tablicę nazw znaczników elementów z podaną klasą, użyj funkcji mapowania:

    // Arrow function (ES2015):
    var divs = Array.from(document.querySelectorAll(".some-class"), element => element.tagName);
    
    // Standard function (since `Array.from` can be shimmed):
    var divs = Array.from(document.querySelectorAll(".some-class"), function(element) {
        return element.tagName;
    });
    

Zastrzeżenie dla hosta-pod warunkiem obiekty

Jeśli używasz Array.prototype funkcji z obiektami typu array (listy DOM i inne rzeczy dostarczane przez przeglądarkę, a nie silnik JavaScript), musisz upewnić się, że testujesz w swoich środowiskach docelowych, aby upewnić się, że obiekt typu host zachowuje się poprawnie. Większość zachowuje się prawidłowo (teraz), ale ważne jest, aby przetestować. Powodem jest to, że większość metod Array.prototype, których prawdopodobnie chcesz użyć, opiera się na obiekcie dostarczonym przez hosta, dając szczera odpowiedź na abstrakcję [[HasProperty]] operacja. W momencie pisania tego tekstu przeglądarki wykonują bardzo dobrą robotę, ale specyfikacja 5.1 pozwoliła na to, że obiekt dostarczany przez host może nie być uczciwy. Jest w §8.6.2, na początku tej sekcji znajduje się kilka akapitów pod dużą tabelą, gdzie jest napisane:

Obiekty hosta mogą zaimplementować te wewnętrzne metody w dowolny sposób, chyba że określono inaczej; na przykład jedną z możliwości jest to, że [[Get]] i [[Put]] dla konkretnego obiektu hosta rzeczywiście pobiera i przechowuje wartości właściwości, ale [[HasProperty]] zawsze generuje false.

(nie mogłem znaleźć równoważnej wersji w specyfikacji ES2015, ale na pewno nadal tak jest.) Ponownie, w momencie pisania tego typu obiektów w nowoczesnych przeglądarkach [NodeList instancje, na przykład] robią obsługują [[HasProperty]] poprawnie, ale ważne jest, aby przetestować.)

 6107
Author: T.J. Crowder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-16 13:23:53

Edit : ta odpowiedź jest beznadziejnie nieaktualna. Aby uzyskać bardziej nowoczesne podejście, spójrz na metody dostępne w tablicy . Metody zainteresowań mogą być:

  • forEach
  • Mapa
  • filtr
  • zip
  • reduce
  • każdy
  • niektóre

Standardowy sposób iteracji tablicy w JavaScript to vanilla for - loop:

var length = arr.length,
    element = null;
for (var i = 0; i < length; i++) {
  element = arr[i];
  // Do something with element
}

Należy jednak pamiętać, że takie podejście jest dobre tylko wtedy, gdy masz gęsta tablica, a każdy indeks jest zajęty przez element. Jeśli tablica jest rzadka, to możesz napotkać problemy z wydajnością z tym podejściem, ponieważ będziesz iteracją wielu indeksów, które nie istnieją naprawdę w tablicy. W tym przypadku pętla for .. in może być lepszym pomysłem. jednakże , musisz użyć odpowiednich zabezpieczeń, aby upewnić się, że działają tylko pożądane właściwości tablicy (tzn. elementy tablicy), ponieważ pętla for..in - będzie również wyliczona w starsze przeglądarki, lub jeśli dodatkowe właściwości są zdefiniowane jako enumerable.

W ECMAScript 5 w prototypie tablicy znajdzie się metoda forEach, ale nie jest ona obsługiwana w starszych przeglądarkach. Aby móc używać go konsekwentnie, musisz mieć środowisko, które go wspiera (na przykład Node.js dla JavaScript po stronie serwera), lub użyć "Polyfill". Polyfill dla tej funkcjonalności jest jednak banalny, a ponieważ sprawia, że kod jest łatwiejszy do odczytania, jest to dobry polyfill to include.

 455
Author: PatrikAkerstrand,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-06 06:11:45

Jeśli używasz jQuery biblioteki, możesz użyć jQuery.każdy:

$.each(yourArray, function(index, value) {
  // do your stuff here
});

EDIT:

Jak na pytanie, użytkownik chce kod w javascript zamiast jquery więc edycja jest

var length = yourArray.length;   
for (var i = 0; i < length; i++) {
  // Do something with yourArray[i].
}
 207
Author: Poonam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-12 05:17:40

Pętla do tyłu

Myślę, że odwrotność dla pętli zasługuje na wzmiankę tutaj:

for (var i = array.length; i--; ) {
     // process array[i]
}

Zalety:

  • nie musisz deklarować tymczasowej zmiennej len ani porównywać z array.length przy każdej iteracji, z których każda może być minutową optymalizacją.
  • usuwanie rodzeństwa Z DOM w odwrotnej kolejności jest zwykle bardziej efektywne. (Przeglądarka musi mniej przesuwać elementy w swojej wewnętrznej tablice.)
  • jeśli zmodyfikujesz tablicę podczas zapętlania, przy indeksie i lub po nim (na przykład usuniesz lub wstawisz element w array[i]), wtedy pętla do przodu pominie element, który został przesunięty w lewo na pozycję i , lub ponownie przetworzy i ten element, który został przesunięty w prawo. W tradycyjnej pętli for można zaktualizować i , aby wskazać następny element, który wymaga przetworzenia - 1, ale po prostu odwrócenie kierunku iteracji jest często prostsze i bardziej eleganckie rozwiązanie .
  • podobnie, podczas modyfikowania lub usuwania zagnieżdżonych elementów DOM, przetwarzanie w odwrotnej kolejności może obejść błędy. Na przykład rozważ modyfikację innerHTML węzła nadrzędnego przed obsługą jego dzieci. Do czasu osiągnięcia węzła potomnego zostanie on odłączony od DOM, po zastąpieniu go nowo utworzonym węzłem potomnym, gdy rodzic został napisany innerHTML.
  • jest krótszy aby wpisać, i czytać , niż niektóre z innych dostępnych opcji. Chociaż przegrywa z forEach() i z for ... of ES6.

Wady:

  • przetwarza elementy w odwrotnej kolejności. Jeśli budujesz nową tablicę z wyników lub drukujesz rzeczy na ekranie, naturalnie wynik zostanie odwrócony w stosunku do pierwotnej kolejności.
  • wielokrotne wstawianie rodzeństwa do domu jako pierwszego dziecka w celu zachowania porządku jest mniej efektywny . (Przeglądarka musiałaby ciągle przesuwać rzeczy w prawo.) Aby tworzyć węzły DOM sprawnie i w porządku, wystarczy zapętlić do przodu i dołączyć jak zwykle (a także użyć "fragmentu dokumentu").
  • odwrotna pętla jest myląca dla młodszych programistów. (Można uznać, że zaletą, w zależności od perspektywy.)

Czy zawsze powinienem go używać?

Niektórzy programiści używają odwrotnej pętli domyślnie, chyba że istnieje dobry powód pętla do przodu.

Chociaż wzrost wydajności jest zwykle nieznaczny, to w pewnym sensie krzyczy:]}

"po prostu zrób to do każdego elementu na liście, nie obchodzi mnie kolejność!"

Jednak w praktyce jest to Nie w rzeczywistości wiarygodnym wskazaniem intencji, ponieważ jest to nieodróżnialne od tych przypadków, gdy do dbać o porządek i naprawdę zrobić potrzeba zapętlić w odwrotnej kolejności. Więc faktycznie potrzebny byłby inny konstrukt, aby dokładnie wyrazić intencję" don 't care", coś obecnie niedostępnego w większości języków, w tym ECMAScript, ale który można by nazwać na przykład forEachUnordered().

Jeśli kolejność nie ma znaczenia, A wydajność jest problemem (w najbardziej wewnętrznej pętli silnika gry lub animacji), to może być dopuszczalne użycie pętli odwrotnej Dla jako wzorca. Pamiętaj tylko, że zobaczenie pętli odwrotnej dla w istniejącym kodzie Nie musi oznaczać , że kolejność nieistotna!

Lepiej jest użyć forEach ()

Ogólnie dla kodu wyższego poziomu, gdzie przejrzystość i bezpieczeństwo są większe obawy, polecam użycie Array::forEach jako domyślny wzór:

  • jest jasne, aby przeczytać.
  • oznacza to, że i nie zostanie przesunięty w obrębie bloku (co jest zawsze możliwą niespodzianką ukrywającą się w długich pętlach for i while.)
  • daje masz wolną przestrzeń do zamykania.
  • zmniejsza wyciek zmiennych lokalnych i przypadkowe kolizje z (i mutacji) zmiennych zewnętrznych.

Wtedy, gdy widzisz pętlę odwrotną dla kodu, jest to wskazówka, że jest ona odwrócona z ważnego powodu (być może z jednego z powodów opisanych powyżej). A widzenie tradycyjnej pętli For do przodu może wskazywać, że przesunięcie może mieć miejsce.

(jeśli dyskusja na temat intencji nie ma dla Ciebie sensu, to Ty i twój kod możecie skorzystaj z wykładu Crockforda na temat styl programowania i twój mózg .)


Jak to działa?
for (var i = 0; i < array.length; i++) { ... }   // Forwards

for (var i = array.length; i--; )    { ... }   // Reverse

Zauważysz, że i-- jest środkową klauzulą (gdzie zwykle widzimy porównanie), a ostatnia klauzula jest pusta (gdzie zwykle widzimy i++). Oznacza to, że i-- jest również używany jako warunek dla kontynuacji. Co najważniejsze, jest ona wykonywana i sprawdzana przed każdą iteracją.

  • Jak to zacząć od array.length bez eksplodowania?

    Ponieważ i-- uruchamia przed każdą iteracją, na pierwszej iteracji będziemy mieli dostęp do elementu w array.length - 1, co pozwala uniknąć problemów z Array-out-of-bounds undefined pozycji.

  • Dlaczego nie przestaje iteracji przed indeksem 0?

    Pętla zatrzyma iterację, gdy warunek i-- obliczy wartość FALSE ' a (gdy Da 0).

    Sztuczka polega na tym, że w przeciwieństwie do --i, Operator końcowy i-- zmniejsza i, ale daje wartość przed dekret. Twoja konsola może to zademonstrować:

    > var i = 5; [i, i--, i];

    [5, 5, 4]

    Więc na ostatecznej iteracji, i był wcześniej 1 i wyrażenie i-- zmienia je na 0 ale faktycznie daje 1 (truthy), a więc warunek mija. W następnej iteracji i-- zmienia i na -1 ale plony 0 (false), powodując natychmiastowe opuszczenie dolnej części pętli.

    W tradycyjnym forward for loop, i++ i ++i są wymienne (jak wskazuje Douglas Crockford). Jednak w odwrotnej pętli for, ponieważ nasz dekrement jest również naszym wyrażeniem warunkowym, musimy trzymać się i-- jeśli chcemy przetworzyć element w indeksie 0.


Ciekawostki

Niektórzy lubią rysować małą strzałkę na odwrocie for pętla, i koniec z przymrużeniem oka:

for (var i = array.length; i --> 0 ;) {

/ align = "center" bgcolor = "# e0ffe0 " / cesarz chin / / align = center /

 88
Author: joeytwiddle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:03:09

Niektóre języki C używają foreach do pętli przez wyliczenia. W JavaScript odbywa się to za pomocą for..in Struktura pętli :

var index,
    value;
for (index in obj) {
    value = obj[index];
}
Jest pewien haczyk. for..in będzie przeszukiwać każdy z elementów obiektu oraz elementy znajdujące się na jego prototypie. Aby uniknąć odczytu wartości dziedziczonych przez prototyp obiektu, po prostu sprawdź, czy właściwość należy do obiektu:
for (i in obj) {
    if (obj.hasOwnProperty(i)) {
        //do stuff
    }
}

Dodatkowo, ECMAScript 5 dodał forEach metoda Array.prototype, która może być użyta do wyliczenia tablicy za pomocą kalbacka (polyfill jest w dokumentach, więc nadal możesz go używać w starszych przeglądarkach):

arr.forEach(function (val, index, theArray) {
    //do stuff
});

Ważne jest, aby pamiętać, że Array.prototype.forEach nie pęka, gdy callback zwraca false. jQuery i podkreślenie.js zapewniają własne wariacje na each, aby zapewnić pętle, które mogą być zwarte.

 72
Author: zzzzBov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-13 01:18:21

Jeśli chcesz zapętlić tablicę, użyj standardowej trzyczęściowej pętli for.

for (var i = 0; i < myArray.length; i++) {
    var arrayItem = myArray[i];
}

Możesz uzyskać kilka optymalizacji wydajności poprzez buforowanie myArray.length lub iterację nad nim wstecz.

 31
Author: Quentin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-17 13:55:46

A forEach implementation (Zobacz w jsFiddle):

function forEach(list,callback) {
  var length = list.length;
  for (var n = 0; n < length; n++) {
    callback.call(list[n]);
  }
}

var myArray = ['hello','world'];

forEach(
  myArray,
  function(){
    alert(this); // do something
  }
);
 25
Author: nmoliveira,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-18 12:22:55

Jeśli nie masz nic przeciwko opróżnieniu tablicy:

var x;

while(x = y.pop()){ 

    alert(x); //do something 

}

x będzie zawierać ostatnią wartość y i zostanie usunięta z tablicy. Możesz również użyć shift(), która da i usunie pierwszy element z y.

 25
Author: gaby de wilde,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-30 18:37:32

Wiem, że to stary post, a jest już tak wiele świetnych odpowiedzi. Dla większej kompletności pomyślałem, że dorzucę jeszcze jedną używając AngularJS. Oczywiście, dotyczy to tylko jeśli używasz Angular, oczywiście, niemniej jednak chciałbym to ująć i tak.

angular.forEach pobiera 2 argumenty i opcjonalny trzeci argument. Pierwszym argumentem jest obiekt (tablica) do iteracji, drugim argumentem jest funkcja iteratora, a opcjonalnym trzecim argumentem jest obiekt kontekst (w zasadzie określany wewnątrz pętli jako "this".

Istnieją różne sposoby wykorzystania pętli foreach kątowej. Najprostszym i prawdopodobnie najczęściej używanym jest

var temp = [1, 2, 3];
angular.forEach(temp, function(item) {
    //item will be each element in the array
    //do something
});

Innym sposobem, który jest przydatny do kopiowania elementów z jednej tablicy do drugiej jest

var temp = [1, 2, 3];
var temp2 = [];
angular.forEach(temp, function(item) {
    this.push(item); //"this" refers to the array passed into the optional third parameter so, in this case, temp2.
}, temp2);
Jednak nie musisz tego robić, możesz po prostu wykonać następujące czynności i jest to równoważne z poprzednim przykładem:]}
angular.forEach(temp, function(item) {
    temp2.push(item);
});

Teraz są plusy i minusy używania funkcji angular.forEach w przeciwieństwie do wbudowanej w pętli o smaku waniliowym for.

Plusy

  • łatwa czytelność
  • łatwa pisownia
  • jeśli jest dostępny, angular.forEach użyje pętli ES5 forEach. Teraz przejdę do efficiency w sekcji cons, ponieważ pętle forEach są dużo wolniejsze niż pętle for. Wspominam o tym jako profesjonalista, ponieważ miło jest być konsekwentnym i ustandaryzowanym.

Rozważ następujące 2 zagnieżdżone pętle, które robią dokładnie to samo. Powiedzmy, że my mają 2 tablice obiektów i każdy obiekt zawiera tablicę wyników, z których każdy ma właściwość Value, która jest ciągiem znaków (lub cokolwiek innego). I powiedzmy, że musimy iterować nad każdym z wyników i jeśli są równe, wykonaj jakąś akcję: {]}

angular.forEach(obj1.results, function(result1) {
    angular.forEach(obj2.results, function(result2) {
        if (result1.Value === result2.Value) {
            //do something
        }
    });
});

//exact same with a for loop
for (var i = 0; i < obj1.results.length; i++) {
    for (var j = 0; j < obj2.results.length; j++) {
        if (obj1.results[i].Value === obj2.results[j].Value) {
            //do something
        }
    }
}

Przyznaję, że jest to bardzo prosty hipotetyczny przykład, ale napisałem triple embedded dla pętli za pomocą drugiego podejścia i było to Bardzo trudne do odczytania i napisania Materia.

Cons

  • efektywność. angular.forEach, a rodzime forEach, w tym przypadku, są zarównoo wiele wolniejsze niż normalna for pętla....o 90% wolniej . W przypadku dużych zbiorów danych najlepiej trzymać się natywnej pętli for.
  • brak wsparcia break, continue, lub return. continue jest rzeczywiście wspierany przez " wypadek", aby kontynuować w angular.forEach wystarczy umieścić return; w funkcji jak angular.forEach(array, function(item) { if (someConditionIsTrue) return; });, co spowoduje, że kontynuuj z funkcji dla tej iteracji. Wynika to również z faktu, że natywny forEach również nie obsługuje break lub continue.

Jestem pewien, że są też inne plusy i minusy, i nie krępuj się dodawać dowolnych, które uznasz za odpowiednie. Czuję, że, podsumowując, jeśli potrzebujesz wydajności, trzymaj się tylko natywnej pętli for dla swoich potrzeb pętli. Ale jeśli twoje zbiory danych są mniejsze i pewna wydajność jest w porządku, aby zrezygnować w zamian za czytelność i pisowalność, więc rzuć angular.forEach w tego niegrzecznego chłopca.

 25
Author: user2359695,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-20 22:56:52

Łatwym rozwiązaniem byłoby teraz użycie podkreślenia .biblioteka js . Zapewnia wiele przydatnych narzędzi, takich jak {[1] } i automatycznie deleguje zadanie do natywnego forEach, jeśli jest dostępne.

Przykład kodu Jak to działa to:

var arr = ["elemA", "elemB", "elemC"];
_.each(arr, function(elem, index, ar)
{
...
});

Zobacz też

 24
Author: Micka,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-30 22:23:09

Prawdopodobnie pętla for(i = 0; i < array.length; i++) nie jest najlepszym wyborem. Dlaczego? Jeśli masz to:

var array = new Array();
array[1] = "Hello";
array[7] = "World";
array[11] = "!";

Metoda wywoła z array[0] do array[2]. Po pierwsze, spowoduje to odniesienie do zmiennych, których nawet nie masz, po drugie, nie będziesz miał zmiennych w tablicy, a po trzecie, spowoduje to, że kod będzie odważniejszy. Spójrz tutaj, to jest to, czego używam:

for(var i in array){
    var el = array[i];
    //If you want 'i' to be INT just put parseInt(i)
    //Do something with el
}

I jeśli chcesz, aby to była funkcja, możesz to zrobić:

function foreach(array, call){
    for(var i in array){
        call(array[i]);
    }
}

Jeśli chcesz złamać, trochę więcej logika:

function foreach(array, call){
    for(var i in array){
        if(call(array[i]) == false){
            break;
        }
    }
}

Przykład:

foreach(array, function(el){
    if(el != "!"){
        console.log(el);
    } else {
        console.log(el+"!!");
    }
});

Zwraca:

//Hello
//World
//!!!
 21
Author: Federico Piragua,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-08 10:49:27

Istnieją trzy implementacje foreach w jQuery w następujący sposób.

var a = [3,2];

$(a).each(function(){console.log(this.valueOf())}); //Method 1
$.each(a, function(){console.log(this.valueOf())}); //Method 2
$.each($(a), function(){console.log(this.valueOf())}); //Method 3
 21
Author: Rajesh Paul,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-08 10:50:06

Od ES6:

list = [0, 1, 2, 3]
for (let obj of list) {
    console.log(obj)
}

Gdzie of unika dziwności związanych z in i sprawia, że działa jak pętla {[3] } dowolnego innego języka, a let wiąże i wewnątrz pętli w przeciwieństwie do funkcji.

Klamry ({}) można pominąć, gdy istnieje tylko jedno polecenie (np. w powyższym przykładzie).

 19
Author: Zaz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-20 15:21:43

Nie ma żadnej pętli for each w natywnym JavaScript. Możesz użyć bibliotek, aby uzyskać tę funkcjonalność (polecam Underscore.js), użyj prostej {[3] } W pętli.

for (var instance in objects) {
   ...
}

Należy jednak pamiętać, że mogą być powody, aby użyć jeszcze prostszej pętli for (Zobacz pytanie o przepełnienie stosuDlaczego jest za pomocą "for...in" z iteracją tablicy taki zły pomysł?)

var instance;
for (var i=0; i < objects.length; i++) {
    var instance = objects[i];
    ...
}
 15
Author: joidegn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:47:36

Jest to iterator dla listy nieliniowej, gdzie indeks zaczyna się od 0, co jest typowym scenariuszem w przypadku dokumentu.getElementsByTagName lub document.querySelectorAll)

function each( fn, data ) {

    if(typeof fn == 'string')
        eval('fn = function(data, i){' + fn + '}');

    for(var i=0, L=this.length; i < L; i++) 
        fn.call( this[i], data, i );   

    return this;
}

Array.prototype.each = each;  

Przykłady użycia:

Przykład #1

var arr = [];
[1, 2, 3].each( function(a){ a.push( this * this}, arr);
arr = [1, 4, 9]

Przykład #2

each.call(document.getElementsByTagName('p'), "this.className = data;",'blue');

Każdy znacznik P dostaje class="blue"

Przykład #3

each.call(document.getElementsByTagName('p'), 
    "if( i % 2 == 0) this.className = data;",
    'red'
);

Co drugi znacznik P dostaje class="red">

Przykład #4

each.call(document.querySelectorAll('p.blue'), 
    function(newClass, i) {
        if( i < 20 )
            this.className = newClass;
    }, 'green'
);

I wreszcie pierwsze 20 niebieskich znaczników p zmienia się na zielone

Uwaga Podczas używania ciągu znaków jako funkcji: funkcja jest tworzona poza kontekstem i powinna być używana tylko wtedy, gdy masz pewność zakresu zmiennych. W przeciwnym razie lepiej przekazać funkcje, w których zasięg jest bardziej intuicyjny.

 15
Author: Tim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-29 12:28:20

Istnieje kilka sposobów pętli przez tablicę w JavaScript, jak poniżej:

Dla - jest to najczęstsze. Pełny blok kodu do zapętlania

var languages = ["JAVA", "JavaScript", "C#", "Python"];
var i, len, text;
for (i = 0, len = languages.length, text = ""; i < len; i++) {
    text += languages[i] + "<br>";
}
document.getElementById("example").innerHTML = text;
<p id="example"></p>

While - pętla while warunek jest skończony. Wydaje się być najszybszą pętlą

var text = "";
var i = 0;
while (i < 10) {
    text +=  i + ") something<br>";
    i++;
}
document.getElementById("example").innerHTML = text;
<p id="example"></p>

Do / while - również Pętla przez blok kodu, gdy warunek jest true, uruchomi co najmniej jeden CZAS

var text = ""
var i = 0;
do {
    text += i + ") something <br>";
    i++;
}
while (i < 10);
document.getElementById("example").innerHTML = text;
<p id="example"></p>

Pętle funkcjonalne - forEach, map, filter, również reduce (pętli przez funkcję, ale używane, jeśli trzeba zrobić coś z tablicy, itp.

// For example, in this case we loop through the number and double them up using the map function
var numbers = [65, 44, 12, 4];
document.getElementById("example").innerHTML = numbers.map(function(num){return num * 2});
<p id="example"></p>

Aby uzyskać więcej informacji i przykładów na temat programowania funkcyjnego na tablicach, zajrzyj do wpisu na bloguprogramowanie funkcjonalne w JavaScript: mapowanie, filtrowanie i redukowanie.

 14
Author: Alireza,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-27 12:29:50

Nie ma wbudowanej możliwości włamania się forEach. Aby przerwać wykonanie użyj Array#some Jak poniżej:

[1,2,3].some(function(number) {
    return number === 1;
});

To działa, ponieważ some zwraca true tak szybko, jak każde wywołanie zwrotne, wykonane w kolejności tablicy, zwraca true, co powoduje zwarcie wykonania reszty. Oryginalna Odpowiedź zobacz prototyp tablicy dla niektórych

 12
Author: Priyanshu Chauhan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:59

ECMAScript5 (Wersja Na Javascript)do pracy z tablicami.

ForEach - iteruje każdy element w tablicy i robi z każdym elementem wszystko, czego potrzebujesz.

['C', 'D', 'E'].forEach(function(element, index) {
  console.log(element + " is the #" + (index+1) + " in musical scale");
});

// Output
// C is the #1 in musical scale
// D is the #2 in musical scale
// E is the #3 in musical scale

W przypadku , bardziej zainteresowany działaniem na tablicy przy użyciu jakiejś wbudowanej funkcji.

Map - tworzy nową tablicę z wynikiem funkcji callback. Ta metoda jest dobra do użycia, gdy trzeba sformatować elementy tablicy.

// Let's upper case the items in the array
['bob', 'joe', 'jen'].map(function(elem) {
  return elem.toUpperCase();
});

// Output: ['BOB', 'JOE', 'JEN']

Reduce - jako nazwa mówi, że zmniejsza tablicę do pojedynczej wartości przez wywołanie danej funkcji przechodzącej w elemencie currenct i wynik poprzedniego wykonania.

[1,2,3,4].reduce(function(previous, current) {
  return previous + current;
});
// Output: 10
// 1st iteration: previous=1, current=2 => result=3
// 2nd iteration: previous=3, current=3 => result=6
// 3rd iteration: previous=6, current=4 => result=10

Every - zwraca true lub false, jeśli wszystkie elementy w tablicy przeszły test w funkcji callback.

// Check if everybody has 18 years old of more.
var ages = [30, 43, 18, 5];  
ages.every(function(elem) {  
  return elem >= 18;
});

// Output: false

Filter - bardzo podobny do każdego z wyjątkiem tego, że filtr zwraca tablicę z elementami, które zwracają true do podanej funkcji.

// Finding the even numbers
[1,2,3,4,5,6].filter(function(elem){
  return (elem % 2 == 0)
});

// Output: [2,4,6]
Mam nadzieję, że to się przyda.
 12
Author: Anil Kumar Arya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-30 17:36:57

Chciałbym również dodać to jako kompozycję odwrotnej pętli i odpowiedź powyżej dla kogoś, kto chciałby tę składnię też.

var foo = [object,object,object];
for (var i = foo.length, item; item = foo[--i];) {
    console.log(item);
}

Plusy:

Korzyści z tego: masz referencję już w pierwszym, jak, że nie będzie musiał być zadeklarowany później z innej linii. Jest to przydatne przy zapętlaniu przez tablicę obiektów.

Wady:

Zostanie przerwane, gdy Referencja będzie false-False (undefined, etc.). Może być stosowany jako ale przewaga. Byłoby to jednak nieco trudniejsze do odczytania. A także w zależności od przeglądarki może być "nie" zoptymalizowany, aby działał szybciej niż oryginalna.

 9
Author: Volkan Seçkin Akbayır,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-19 16:27:44

JQuery way using $.map:

var data = [1, 2, 3, 4, 5, 6, 7];

var newData = $.map(data, function(element) {
    if (element % 2 == 0) {
        return element;
    }
});

// newData = [2, 4, 6];
 8
Author: DanFromGermany,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-01 11:15:26

Najbardziej zbliżonym sposobem do twojego pomysłu byłoby użycie Array.forEach(), które akceptuje funkcję clojure, która będzie wykonywana dla każdego elementu tablicy.

myArray.forEach(
  (item) => {
    // do something 
    console.log(item);
  }
);

Innym realnym sposobem byłoby użycie Array.map(), które działa w ten sam sposób, ale również mutates każdy element i zwraca go w następujący sposób:

var myArray = [1, 2, 3];
myArray = myArray.map(
  (item) => {
    return item + 1;
  }
);

console.log(myArray); // [2, 3, 4]
 4
Author: Ante Jablan Adamović,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-09 15:31:44

Składnia lambda zwykle nie działa w IE 10 lub poniżej.

Zwykle używam

[].forEach.call(arrayName,function(value,index){
    console.log("value of the looped element" + value);
    console.log("index of the looped element" + index);
});


If you are a jQuery Fan and already have a jQuery file running, you should reverse the positions of the index and value parameters

$("#ul>li").each(function(**index,value**){
    console.log("value of the looped element" + value);
    console.log("index of the looped element" + index);
});
 3
Author: Murtuza Husain,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-16 08:09:53
var a = ["car", "bus", "truck"]
a.forEach(function(item, index) {
    console.log("Index" + index);
    console.log("Element" + item);
})
 1
Author: John,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-15 22:48:33

Możesz wywołać forEach tak:

let Array = [1,3,2];

theArray.forEach((element)=>{ 
  // use the element of the array
  console.log(element) 
}

Element będzie miał wartość każdego indeksu od 0 do długości tablicy.

Wyjście:

1    
3    
2

Wyjaśnienie:

ForEach jest w klasie prototypów. można to również nazwać theArray.prototyp.forEach(...);

Prototyp: https://hackernoon.com/prototypes-in-javascript-5bba2990e04b

Możesz również zmieniać tablicę tak:

for(let i=0;i<theArray.length;i++){
  console.log(i); //i will have the value of each index
}
 1
Author: Nouman Dilshad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-17 12:30:51

Jeśli chcesz użyć forEach(), będzie to wyglądało tak: -

theArray.forEach ( element => { console.log(element); });

Jeśli chcesz użyć for(), będzie to wyglądało tak: -

for(let idx = 0; idx < theArray.length; idx++){ let element = theArray[idx]; console.log(element); }

 0
Author: Harunur Rashid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-30 09:05:30

Jeśli masz masywną tablicę powinieneś użyć iterators aby zyskać trochę wydajności. Iteratory są własnością pewnych kolekcji JavaScript (jak Map, Set, String, Array). Parzyste, for..of zastosowania iterator pod maską.

Iteratory zwiększają wydajność, pozwalając użytkować po kolei przedmioty z listy, tak jakby były strumieniem. Iterator wyróżnia się tym, jak przemierza kolekcja. Inne pętle muszą załadować całą kolekcję z przodu, aby iterować nad nią, podczas gdy iterator musi znać tylko bieżącą pozycję w kolekcji.

Dostęp do bieżącego elementu można uzyskać, wywołując metodę iteratora next. Następna metoda zwróci value bieżącej pozycji oraz boolean aby wskazać, kiedy dotarłeś do końca kolekcji. Poniżej przedstawiono przykład tworzenia iteratora z tablicy.

Przekształć zwykłą tablicę w iterator używając values() metoda jak ta:

    const myArr = [2,3,4]

let it = myArr.values();

console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());

Możesz również przekształcić zwykłą tablicę do iteratora za pomocą Symbol.iterator tak:

const myArr = [2,3,4]

let it = myArr[Symbol.iterator]();

console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());

Możesz również przekształcić swoje zwykłe array W iterator tak:

let myArr = [8, 10, 12];

function makeIterator(array) {
    var nextIndex = 0;
    
    return {
       next: function() {
           return nextIndex < array.length ?
               {value: array[nextIndex++], done: false} :
               {done: true};
       }
    };
};

var it = makeIterator(myArr);

console.log(it.next().value);   // {value: 8, done: false}
console.log(it.next().value);   // {value: 10, done: false}
console.log(it.next().value);   // {value: 12, done: false}
console.log(it.next().value);   // {value: undefined, done: true}

Uwaga :

  • Iteratory są wyczerpujące w naturze.
  • obiekty nie są domyślnie iterable. Użycie for..in W takim przypadku, ponieważ zamiast wartości działa z kluczami.

Możesz przeczytać więcej o iteration protocol tutaj .

 0
Author: BlackBeard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-06 11:32:03

Podsumowanie:

Podczas iteracji tablicy często możemy chcieć osiągnąć jeden z następujących celów:]}

  1. Chcemy iterację nad tablicą i utworzyć nową tablicę:

    Array.prototype.map

  2. Chcemy iterację nad tablicą i nie tworzyć nowej tablicy:

    Array.prototype.forEach

    for..of pętla

W JS jest wiele sposobów na osiągnięcie obu tych celów. Jednak niektóre z nich są bardziej conventient niż inni. Poniżej znajdziesz kilka powszechnie używanych metod (najbardziej conventient imo) do wykonania iteracji tablicy w javascript.

Tworzenie nowej tablicy: Map

map() jest funkcją znajdującą się na Array.prototype, która może przekształcić każdy element tablicy, a następnie zwraca nową tablicę. map() przyjmuje jako argument funkcję zwrotną i działa w następujący sposób:

let arr = [1, 2, 3, 4, 5];

let newArr = arr.map((element, index, array) => {
  return element * 2;
})

console.log(arr);
console.log(newArr);

Wywołanie zwrotne, które przekazaliśmy map() jako argument jest wykonywany dla każdego elementu. Następnie zwracana jest tablica, która ma taką samą długość jak oryginalna tablica. W tej nowej tablicy element jest przekształcany przez funkcję wywołania zwrotnego przekazaną jako argument do map().

Różnica pomiędzy map a innym mechanizmem pętli, takim jak forEach i pętla for..of jest taka, że map zwraca jako nową tablicę i pozostawia starą tablicę nienaruszoną (chyba że explicity manipuluje nią myślami w stylu splice).

Zobacz też że wywołanie zwrotne funkcji map dostarcza jako drugi argument Numer indeksu bieżącej iteracji. Ponadto trzeci argument podaje tablicę, na której wywołano map. Czasami te właściwości mogą być bardzo przydatne.

Pętla za pomocą forEach

forEach jest funkcją znajdującą się na Array.prototype, która przyjmuje funkcję zwrotną jako argument. Następnie wykonuje tę funkcję zwrotną dla każdego elementu w tablicy. W przeciwieństwie do funkcji map() forEach funkcja nie zwraca nic (undefined). Na przykład:

let arr = [1, 2, 3, 4, 5];

arr.forEach((element, index, array) => {

  console.log(element * 2);

  if (index === 4) {
    console.log(array)
  }
  // index, and oldArray are provided as 2nd and 3th argument by the callback

})

console.log(arr);

Podobnie jak funkcja map, wywołanie zwrotne forEach dostarcza jako drugi argument Numer indeksu bieżącej iteracji. Trzeci argument podaje również tablicę, na której wywołano forEach.

Pętla przez elementy za pomocą for..of

Pętla for..of przenika przez każdy element tablicy (lub inny obiekt iteracyjny). Działa w następujących sposób:

let arr = [1, 2, 3, 4, 5];

for(let element of arr) {
  console.log(element * 2);
}

W powyższym przykładzie element oznacza element tablicy i {[31] } jest tablicą, którą chcemy zapętlić. Nie, że nazwa {[30] } jest arbitralna i moglibyśmy wybrać dowolną inną nazwę, taką jak ' el ' lub coś bardziej deklaratywnego, gdy ma to zastosowanie.

Nie myl pętli for..in z pętlą for..of. for..in będzie w pętli przez wszystkie właściwości tablicy, podczas gdy pętla for..of będzie w pętli tylko przez elementy tablicy. Na przykład:

let arr = [1, 2, 3, 4, 5];

arr.foo = 'foo';

for(let element of arr) {
  console.log(element);
}

for(let element in arr) {
  console.log(element);
}
 0
Author: Willem van der Veen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-08 10:11:23

function printList(callback) {
    // do your printList work
    console.log('printList is done');
    callback();
}

function updateDB(callback) {
    // do your updateDB work
    console.log('updateDB is done');
    callback()
}

function getDistanceWithLatLong(callback) {
    // do your getDistanceWithLatLong work
    console.log('getDistanceWithLatLong is done');
    callback();
}

function runSearchInOrder(callback) {
    getDistanceWithLatLong(function() {
        updateDB(function() {
            printList(callback);
        });
    });
}

runSearchInOrder(function(){console.log('finished')});

Getdistancewithlong is done updateDB jest zrobione printList is done finished

 -2
Author: Avinash Maurya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-01 10:18:28