it-swarm.com.de

Für-über einem Array in JavaScript?

Wie kann ich mit JavaScript alle Einträge in einem Array durchlaufen?

Ich dachte, es wäre so etwas:

forEach(instance in theArray)

Wo theArray ist mein Array, aber das scheint falsch zu sein.

4056
Dante1986

TL; DR

  • Verwenden Sie for-in nur, wenn Sie es mit Sicherheitsvorkehrungen verwenden oder zumindest wissen, warum es Sie beißen könnte.
  • Ihre besten Wetten sind normalerweise

    • eine for-of-Schleife (nur ES2015 +),
    • Array#forEach ( spec | MDN ) (oder seine Verwandten some und solche) (nur ES5 +),
    • eine einfache altmodische for-Schleife,
    • oder for-in mit Sicherheitsvorkehrungen.

Aber es gibt vielmehr zu entdecken, lesen Sie weiter ...


JavaScript verfügt über eine leistungsstarke Semantik zum Durchlaufen von Arrays und Array-ähnlichen Objekten. Ich habe die Antwort in zwei Teile geteilt: Optionen für echte Arrays und Optionen für Dinge, die nur Array sind - wie , wie das Objekt arguments, andere iterierbare Objekte (ES2015 +) , DOM-Sammlungen und so weiter.

Ich stelle schnell fest, dass Sie die ES2015-Optionen jetzt auch auf ES5-Engines verwenden können, indem Sie ES2015 auf ES5 transpilieren . Suche nach "ES2015 transpiling"/"ES6 transpiling" für mehr ...

Okay, schauen wir uns unsere Optionen an:

Für aktuelle Arrays

Sie haben drei Möglichkeiten in ECMAScript 5 ("ES5"), der derzeit am meisten unterstützten Version, und zwei weitere in ECMAScript 2015 ( "ES2015", "ES6"):

  1. Verwenden Sie forEach und verwandte (ES5 +)
  2. Verwenden Sie eine einfache for-Schleife
  3. Verwende for-in richtig
  4. Verwende for-of (benutze implizit einen Iterator) (ES2015 +)
  5. Verwenden Sie explizit einen Iterator (ES2015 +)

Einzelheiten:

1. Verwenden Sie forEach und verwandte

In einer vage modernen Umgebung (also nicht IE8), in der Sie Zugriff auf die von ES5 hinzugefügten Funktionen Array haben (direkt oder mithilfe von Polyfills), können Sie forEach ( spec | MDN ):

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

forEach akzeptiert eine Rückruffunktion und optional einen Wert, der beim Aufrufen dieses Rückrufs als this verwendet wird (oben nicht verwendet). Der Rückruf wird für jeden Eintrag im Array aufgerufen, um nicht vorhandene Einträge in spärlichen Arrays zu überspringen. Obwohl ich oben nur ein Argument verwendet habe, wird der Rückruf mit drei Argumenten aufgerufen: dem Wert jedes Eintrags, dem Index dieses Eintrags und einem Verweis auf das Array, über das Sie iterieren (falls Ihre Funktion es noch nicht zur Hand hat) ).

Sofern Sie nicht veraltete Browser wie IE8 unterstützen (NetApps weist zum Zeitpunkt dieses Berichts im September 2016 einen Marktanteil von etwas mehr als 4% auf), können Sie forEach problemlos auf einer Allzweck-Webseite ohne Shim verwenden. Wenn Sie veraltete Browser unterstützen müssen, können Sie einfach forEach shimmen/polyfüllen (suchen Sie nach "es5 shim" für mehrere Optionen).

forEach hat den Vorteil, dass Sie keine Indizierungs- und Wertevariablen im enthaltenden Bereich deklarieren müssen, da diese als Argumente für die Iterationsfunktion bereitgestellt werden und daher nur für diese Iteration geeignet sind.

Wenn Sie sich Sorgen über die Laufzeitkosten machen, die beim Ausführen eines Funktionsaufrufs für jeden Array-Eintrag entstehen, sollten Sie dies nicht tun. Details .

Darüber hinaus ist forEach die Funktion "Alle durchschleifen", in ES5 wurden jedoch einige andere nützliche Funktionen definiert, mit denen Sie sich durch das Array arbeiten und Dinge erledigen können, darunter:

  • every (Stoppt die Schleife, wenn der Rückruf zum ersten Mal false oder etwas Falsches zurückgibt.)
  • some (Stoppt die Schleife, wenn der Rückruf zum ersten Mal true oder etwas Wahres zurückgibt.)
  • filter (Erstellt ein neues Array mit Elementen, bei denen die Filterfunktion true zurückgibt, und lässt diejenigen weg, bei denen sie false zurückgibt.)
  • map (erstellt ein neues Array aus den vom Rückruf zurückgegebenen Werten)
  • reduce (baut einen Wert durch wiederholtes Aufrufen des Rückrufs auf, wobei vorherige Werte übergeben werden; Einzelheiten finden Sie in der Spezifikation; nützlich zum Summieren des Inhalts eines Arrays und vielen anderen Dingen)
  • reduceRight (wie reduce, funktioniert jedoch in absteigender und nicht in aufsteigender Reihenfolge)

2. Verwenden Sie eine einfache for-Schleife

Manchmal sind die alten Wege die besten:

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

Wenn sich die Länge des Arrays während der Schleife nicht ändert und es sich um einen leistungsabhängigen Code handelt (unwahrscheinlich), ist eine etwas kompliziertere Version, die die Länge im Voraus ermittelt, möglicherweise ein winzig etwas schneller:

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

Und/oder rückwärts zählen:

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

Bei modernen JavaScript-Engines ist es jedoch selten, dass Sie das letzte bisschen Saft herausholen müssen.

In ES2015 und höher können Sie Ihre Index- und Wertvariablen lokal für die for-Schleife festlegen:

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

Und wenn Sie dies tun, wird nicht nur value, sondern auch index für jede Schleifeniteration neu erstellt. Das bedeutet, dass im Schleifenkörper erstellte Abschlüsse einen Verweis auf die für diese bestimmte Iteration erstellten index (und value) enthalten:

let divs = document.querySelectorAll("div");
for (let index = 0; index < divs.length; ++index) {
    divs[index].addEventListener('click', e => {
        console.log("Index is: " + index);
    });
}
let divs = document.querySelectorAll("div");
for (let index = 0; index < divs.length; ++index) {
    divs[index].addEventListener('click', e => {
        console.log("Index is: " + index);
    });
}
<div>zero</div>
<div>one</div>
<div>two</div>
<div>three</div>
<div>four</div>

Wenn Sie fünf Divs hatten, würden Sie "Index ist: 0" erhalten, wenn Sie auf den ersten klickten, und "Index ist: 4", wenn Sie auf den letzten klickten. Dies funktioniert nicht, wenn Sie var anstelle von let verwenden.

3. Benutze for-in richtig

Sie werden aufgefordert, for-in zu verwenden, aber ist nicht das, wofür for-in ist . for-in durchläuft die aufzählbaren Eigenschaften eines Objekts , nicht die Indizes eines Arrays. Die Reihenfolge ist nicht garantiert, auch nicht in ES2015 (ES6). ES2015 + definiert eine Reihenfolge für Objekteigenschaften (über [[OwnPropertyKeys]] , [[Enumerate]] und Dinge, die sie verwenden, wie Object.getOwnPropertyKeys )), aber es definiert nicht, dass for-in dieser Reihenfolge folgt. (Details in dieser anderen Antwort .)

Die einzigen tatsächlichen Anwendungsfälle für for-in in einem Array sind:

  • Es ist ein spärliches Array mit massivenLücken oder
  • Sie verwenden Eigenschaften, die keine Elemente sind, und möchten sie in die Schleife aufnehmen

Betrachten Sie nur das erste Beispiel: Sie können for-in verwenden, um diese sparsamen Array-Elemente zu besuchen, wenn Sie geeignete Sicherheitsmaßnahmen verwenden:

// `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 checks are
        /^0$|^[1-9]\d*$/.test(key) &&    // explained
        key <= 4294967294                // below
        ) {
        console.log(a[key]);
    }
}

Beachten Sie die drei Prüfungen:

  1. Dass das Objekt seine eigene Eigenschaft unter diesem Namen hat (nicht eine, die es von seinem Prototyp erbt), und

  2. Dass der Schlüssel ausschließlich aus Dezimalstellen besteht (z. B. normale Zeichenfolgenform, keine wissenschaftliche Notation), und

  3. Dass der Wert des Schlüssels, wenn er zu einer Zahl gezwungen wird, <= 2 ^ 32 - 2 ist (das ist 4.294.967.294). Woher kommt diese Nummer? Dies ist Teil der Definition eines Array-Index in der Spezifikation . Andere Zahlen (Nicht-Ganzzahlen, negative Zahlen, Zahlen größer als 2 ^ 32 - 2) sind keine Array-Indizes. Der Grund, warum es 2 ^ 32 - 2ist, ist, dass der größte Indexwert um eins niedriger ist als 2 ^ 32 - 1Maximaler Wert, den das length eines Arrays haben kann. (ZB passt die Länge eines Arrays in eine 32-Bit-Ganzzahl ohne Vorzeichen.) (Fordert RobG auf, in einem Kommentar zu meinem Blog-Post darauf hinzuweisen, dass mein vorheriger Test war nicht ganz richtig.)

Das würden Sie natürlich nicht im Inline-Code machen. Sie würden eine Utility-Funktion schreiben. Vielleicht:

// Utility function for antiquated environments without `forEach`
var hasOwn = Object.prototype.hasOwnProperty;
var rexNum = /^0$|^[1-9]\d*$/;
function sparseEach(array, callback, thisArg) {
    var index;
    for (var key in array) {
        index = +key;
        if (hasOwn.call(a, key) &&
            rexNum.test(key) &&
            index <= 4294967294
            ) {
            callback.call(thisArg, array[key], index, array);
        }
    }
}

var a = [];
a[5] = "five";
a[10] = "ten";
a[100000] = "one hundred thousand";
a.b = "bee";

sparseEach(a, function(value, index) {
    console.log("Value at " + index + " is " + value);
});

4. Verwende for-of (benutze implizit einen Iterator) (ES2015 +)

ES2015 fügt Iteratoren zu JavaScript hinzu. Die einfachste Methode zur Verwendung von Iteratoren ist die neue Anweisung for-of. Es sieht aus wie das:

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

Unter dem Deckmantel erhält das einen Iterator aus dem Array und durchläuft ihn, um die Werte daraus zu erhalten. Dies hat nicht das Problem, dass die Verwendung von for-in vorliegt, da ein durch das Objekt (das Array) definierter Iterator verwendet wird und Arrays definieren, dass ihre Iteratoren durch ihre -Einträge iterieren (nicht) ihre Eigenschaften). Im Gegensatz zu for-in in ES5 entspricht die Reihenfolge, in der die Einträge aufgerufen werden, der numerischen Reihenfolge ihrer Indizes.

5. Verwenden Sie explizit einen Iterator (ES2015 +)

Manchmal möchten Sie einen Iterator explizit verwenden. Sie können das auch tun, obwohl es viel umständlicher ist als for-of. Es sieht aus wie das:

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

Der Iterator ist ein Objekt, das der Iteratordefinition in der Spezifikation entspricht. Die Methode next gibt bei jedem Aufruf ein neues Ergebnisobjekt zurück. Das Ergebnisobjekt hat die Eigenschaft done, die angibt, ob es fertig ist, und die Eigenschaft value mit dem Wert für diese Iteration. (done ist optional, wenn es false wäre, value ist optional, wenn es undefined wäre.)

Die Bedeutung von value hängt vom Iterator ab. Arrays unterstützen (mindestens) drei Funktionen, die Iteratoren zurückgeben:

  • values(): Dies ist die Funktion, die ich oben verwendet habe. Es wird ein Iterator zurückgegeben, bei dem jedes value der Array-Eintrag für diese Iteration ist ("a", "b" und "c" im vorherigen Beispiel).
  • keys(): Gibt einen Iterator zurück, bei dem jedes value der Schlüssel für diese Iteration ist (für unser a wäre dies also "0", dann "1", dann "2").
  • entries(): Gibt einen Iterator zurück, bei dem jedes value ein Array in der Form [key, value] für diese Iteration ist.

Für Array-ähnliche Objekte

Abgesehen von echten Arrays gibt es auch arrayähnliche Objekte mit einer length-Eigenschaft und Eigenschaften mit numerischen Namen: NodeList-Instanzen, das arguments-Objekt usw. Wie durchlaufen wir ihre Inhalt?

Verwenden Sie eine der oben genannten Optionen für Arrays

Zumindest einige und möglicherweise die meisten oder sogar alle der oben genannten Array-Ansätze lassen sich häufig gleichermaßen gut auf arrayähnliche Objekte anwenden:

  1. Verwende forEach und verwandte (ES5 +)

    Die verschiedenen Funktionen von Array.prototype sind "absichtlich generisch" und können normalerweise für arrayähnliche Objekte über Function#call oder Function#apply verwendet werden. (Siehe die Einschränkung für vom Host bereitgestellte Objekte am Ende dieser Antwort, aber es ist ein seltenes Problem.)

    Angenommen, Sie möchten forEach für die Eigenschaft Node einer childNodes verwenden. Das würdest du machen:

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

    Wenn Sie dies häufig tun, möchten Sie möglicherweise eine Kopie der Funktionsreferenz in eine Variable zur Wiederverwendung kopieren, z.

    // (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. Benutze eine einfache for-Schleife

    Offensichtlich gilt eine einfache for-Schleife für arrayähnliche Objekte.

  3. Verwende for-in richtig

    for-in mit den gleichen Sicherheitsvorkehrungen wie bei einem Array sollte auch mit arrayähnlichen Objekten funktionieren. Möglicherweise gilt die Einschränkung für vom Host bereitgestellte Objekte unter Nummer 1.

  4. Verwende for-of (benutze implizit einen Iterator) (ES2015 +)

    for-of verwendet den vom Objekt bereitgestellten Iterator (falls vorhanden). Wir werden sehen, wie dies mit den verschiedenen Array-ähnlichen Objekten, insbesondere den von Host bereitgestellten, funktioniert. Beispielsweise wurde die Spezifikation für NodeList von querySelectorAll aktualisiert, um die Iteration zu unterstützen. Die Spezifikation für die HTMLCollection von getElementsByTagName war nicht.

  5. Verwenden Sie explizit einen Iterator (ES2015 +)

    Siehe # 4, wir müssen sehen, wie Iteratoren ablaufen.

Erstellen Sie ein echtes Array

In anderen Fällen möchten Sie möglicherweise ein Array-ähnliches Objekt in ein echtes Array konvertieren. Das ist überraschend einfach:

  1. Verwenden Sie die slice -Methode von Arrays

    Wir können die slice-Methode von Arrays verwenden, die wie die anderen oben genannten Methoden "absichtlich generisch" ist und daher mit arrayähnlichen Objekten wie folgt verwendet werden kann:

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

    Wenn wir zum Beispiel ein NodeList in ein echtes Array konvertieren möchten, könnten wir dies tun:

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

    Siehe die Einschränkung für vom Host bereitgestellte Objekte weiter unten. Beachten Sie insbesondere, dass dies in IE8 und früheren Versionen fehlschlägt, sodass Sie von Host bereitgestellte Objekte nicht als this verwenden können.

  2. Verwenden Sie die Spread-Syntax (...)

    Es ist auch möglich, ES2015s Spread-Syntax mit JavaScript-Engines zu verwenden, die diese Funktion unterstützen:

    var trueArray = [...iterableObject];
    

    Wenn wir also zum Beispiel ein NodeList in ein echtes Array konvertieren möchten, wird dies mit der Spread-Syntax recht prägnant:

    var divs = [...document.querySelectorAll("div")];
    
  3. Verwenden Sie Array.from(spec) | (MDN)

    Array.from (ES2015 +, aber leicht polyfüllbar) erstellt ein Array aus einem Array-ähnlichen Objekt und leitet die Einträge optional zuerst über eine Zuordnungsfunktion. So:

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

    Wenn Sie ein Array der Tag-Namen der Elemente mit einer bestimmten Klasse abrufen möchten, verwenden Sie die Zuordnungsfunktion:

    // 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;
    });
    

Vorsichtsmaßnahme für vom Host bereitgestellte Objekte

Wenn Sie Array.prototype -Funktionen mit vom Host bereitgestellten arrayähnlichen Objekten (DOM-Listen und andere vom Browser bereitgestellte Dinge anstelle der JavaScript-Engine) verwenden, müssen Sie sicherstellen, dass Sie testen Stellen Sie in den Zielumgebungen sicher, dass sich das vom Host bereitgestellte Objekt ordnungsgemäß verhält. Die meisten verhalten sich richtig(jetzt), aber es ist wichtig zu testen. Der Grund dafür ist, dass die meisten Array.prototype-Methoden, die Sie wahrscheinlich verwenden möchten, darauf beruhen, dass das vom Host bereitgestellte Objekt eine ehrliche Antwort auf die abstrakte [[HasProperty]] -Operation gibt. Zum jetzigen Zeitpunkt machen die Browser dies sehr gut, aber die 5.1-Spezifikation hat die Möglichkeit zugelassen, dass ein vom Host bereitgestelltes Objekt möglicherweise nicht ehrlich ist. Es befindet sich in §8.6.2 , mehrere Absätze unterhalb der großen Tabelle am Anfang dieses Abschnitts, wo es heißt:

Host-Objekte können diese internen Methoden auf beliebige Weise implementieren, sofern nicht anders angegeben. Eine Möglichkeit besteht beispielsweise darin, dass [[Get]] und [[Put]] für ein bestimmtes Host-Objekt zwar Eigenschaftswerte abrufen und speichern, [[HasProperty]] jedoch immer falsegeneriert.

(Ich konnte in der ES2015-Spezifikation kein entsprechendes Wort finden, aber es muss immer noch der Fall sein.) Ab diesem Zeitpunkt werden wieder die allgemeinen vom Host bereitgestellten Array-ähnlichen Objekte in modernen Browsern [NodeList -Instanzen] dohandle [[HasProperty]] richtig, aber es ist wichtig zu testen.)

6662
T.J. Crowder

Edit: Diese Antwort ist hoffnungslos veraltet. Für einen moderneren Ansatz, siehe die verfügbaren Methoden für ein Array . Methoden von Interesse könnten sein:

  • für jeden
  • karte
  • filter
  • Postleitzahl
  • reduzieren
  • jeden
  • etwas

Die Standardmethode zum Durchlaufen eines Arrays in JavaScript ist eine Vanilla for- Schleife:

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

Beachten Sie jedoch, dass dieser Ansatz nur dann gut ist, wenn Sie ein dichtes Array haben und jeder Index von einem Element belegt wird. Wenn das Array spärlich ist, können Sie mit diesem Ansatz auf Leistungsprobleme stoßen, da Sie viele Indizes durchlaufen, die nicht wirklich im Array vorhanden sind. In diesem Fall könnte eine for .. in-Schleife eine bessere Idee sein. Allerdings müssen Sie die entsprechenden Sicherheitsvorkehrungen verwenden, um sicherzustellen, dass nur die gewünschten Eigenschaften des Arrays (d. H. Der Array-Elemente) berücksichtigt werden, da die for..in- Schleife auch in älteren Browsern aufgelistet wird zusätzliche Eigenschaften werden als enumerable definiert.

In ECMAScript 5 gibt es eine forEach-Methode für den Array-Prototyp, diese wird jedoch von älteren Browsern nicht unterstützt. Um es konsequent nutzen zu können, müssen Sie entweder über eine Umgebung verfügen, in der es unterstützt wird (z. B. Node.js für serverseitige JavaScript), oder eine "Polyfill" verwenden. Das Polyfill für diese Funktionalität ist jedoch trivial und da es den Code leichter lesbar macht, ist es ein guter Polyfill.

473

Wenn Sie die Bibliothek jQuery verwenden, können Sie jQuery.each verwenden:

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

EDIT: 

Wie pro Frage möchte der Benutzer Code in Javascript anstelle von jquery, damit die Bearbeitung erfolgt

var length = yourArray.length;   
for (var i = 0; i < length; i++) {
  // Do something with yourArray[i].
}
214
Poonam

Schleife rückwärts

Ich denke, die reverse for-Schleife verdient eine Erwähnung hier:

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

Vorteile:

  • Sie müssen keine temporäre len -Variable deklarieren oder bei jeder Iteration mit array.length Vergleichen, was möglicherweise eine winzige Optimierung darstellt.
  • Geschwister entfernen aus dem DOM in umgekehrter Reihenfolge ist normalerweise effizienter. (Der Browser muss weniger Elemente in seinen internen Arrays verschieben.)
  • Wenn Sie das Array ändern während der Schleife, am oder nach dem Index i (zum Beispiel, wenn Sie ein Element bei array[i] Entfernen oder einfügen), dann ein Forward Die Schleife würde das Element, das nach links verschoben wurde, in die Position i überspringen oder das i -te Element, das nach rechts verschoben wurde, erneut verarbeiten. In einer traditionellen for-Schleife können Sie could update i auf das nächste Element verweisen, das verarbeitet werden muss - 1, aber häufig ist es einfach, die Iterationsrichtung umzukehren einfacher und elegantere Lösung .
  • Ebenso kann beim Ändern oder Entfernen von verschachtelten DOM-Elementen die umgekehrte Verarbeitung Fehler umgehen. Überlegen Sie sich beispielsweise, das innerHTML eines übergeordneten Knotens zu ändern, bevor Sie dessen untergeordnete Knoten behandeln. Wenn der untergeordnete Knoten erreicht ist, wird er vom DOM getrennt und durch ein neu erstelltes untergeordnetes Element ersetzt, als das innere HTML des übergeordneten Knotens geschrieben wurde.
  • Es ist kürzer zu tippen und zu lesen, als einige der anderen verfügbaren Optionen. Es verliert zwar an forEach() und an ES6's for ... of.

Nachteile:

  • Es verarbeitet die Artikel in umgekehrter Reihenfolge. Wenn Sie ein neues Array aus den Ergebnissen erstellen oder Dinge auf dem Bildschirm drucken, ist dies natürlich die Ausgabe wird umgekehrt ​​in Bezug auf die ursprüngliche Reihenfolge.
  • Das wiederholte Einfügen von Geschwistern als erstes Kind in das DOM, um die Reihenfolge beizubehalten, ist weniger effizient. (Der Browser müsste die Dinge immer wieder nach rechts verschieben.) Um DOM-Knoten effizient und in der richtigen Reihenfolge zu erstellen, schleifen Sie einfach vorwärts und hängen Sie sie wie gewohnt an (und verwenden Sie auch ein "Dokumentfragment").
  • Die umgekehrte Schleife ist verwirrend für Nachwuchsentwickler. (Dies kann je nach Outlook von Vorteil sein.)

Soll ich es immer benutzen?

Einige Entwickler verwenden die umgekehrte Methode für loop standardmäßig, es sei denn, es gibt einen guten Grund für eine Schleife vorwärts.

Obwohl die Leistungssteigerungen in der Regel unbedeutend sind, schreit es irgendwie:

"Tun Sie dies einfach für jeden Punkt in der Liste, die Reihenfolge ist mir egal!"

In der Praxis ist dies jedoch nicht ​​ein verlässlicher Hinweis auf die Absicht, da es nicht von den Situationen zu unterscheiden ist, in denen Sie do sich um die Reihenfolge kümmern , und wirklich tun müssen, um rückwärts zu schleifen. Tatsächlich wäre also ein anderes Konstrukt erforderlich, um die Absicht "egal" genau auszudrücken, etwas, das derzeit in den meisten Sprachen, einschließlich ECMAScript, nicht verfügbar ist, das aber beispielsweise forEachUnordered() genannt werden könnte.

Wenn die Reihenfolge keine Rolle spielt und Effizienz ein Problem ist (in der innersten Schleife eines Spiels oder einer Animations-Engine), kann es akzeptabel sein, die umgekehrte for-Schleife als Startmuster zu verwenden. Denken Sie daran, dass eine umgekehrte for-Schleife im vorhandenen Code angezeigt wird bedeutet nicht unbedingt ​​dass die Reihenfolge irrelevant ist!

Es ist besser, forEach () zu verwenden

Im Allgemeinen würde ich für Code auf höherer Ebene, bei dem Klarheit und Sicherheit ​​größere Bedenken bereiten, empfehlen, Array::forEach als Standardmuster zu verwenden:

  • Es ist klar zu lesen.
  • Es zeigt an, dass i nicht innerhalb des Blocks verschoben wird (was immer eine mögliche Überraschung ist, die sich in langen for und while Schleifen verbirgt.)
  • Es gibt Ihnen einen freien Spielraum für Schließungen.
  • Es reduziert den Verlust lokaler Variablen und die versehentliche Kollision mit (und Mutation von) äußeren Variablen.

Wenn Sie dann die umgekehrte for-Schleife in Ihrem Code sehen, ist dies ein Hinweis darauf, dass sie aus einem guten Grund (möglicherweise einem der oben beschriebenen Gründe) umgekehrt ist. Und wenn Sie eine traditionelle Forward for-Schleife sehen, kann dies darauf hinweisen, dass eine Verschiebung stattfinden kann.

(Wenn die Diskussion über Absichten für Sie keinen Sinn ergibt, können Sie und Ihr Code davon profitieren, Crockfords Vortrag über Programming Style & Your Brain .)


Wie funktioniert es?

for (var i = 0; i < array.length; i++) { ... }   // Forwards

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

Sie werden feststellen, dass i-- Die mittlere Klausel ist (wo wir normalerweise einen Vergleich sehen) und die letzte Klausel leer ist (wo wir normalerweise i++ Sehen). Das bedeutet, dass i-- Auch als Bedingung für die Fortsetzung verwendet wird. Entscheidend ist, dass es bei jeder Iteration ausgeführt und überprüft wird vor.

  • Wie kann es bei array.length Beginnen, ohne zu explodieren?

    Da i-- vor bei jeder Iteration ausgeführt wird, greifen wir bei der ersten Iteration tatsächlich auf das Element unter array.length - 1 Zu, wodurch Probleme mit vermieden werden Array außerhalb der Grenzen undefined Elemente.

  • Warum hört es nicht auf, vor Index 0 zu iterieren?

    Die Schleife hört auf zu iterieren, wenn die Bedingung i-- Einen falschen Wert ergibt (wenn sie 0 ergibt).

    Der Trick ist, dass im Gegensatz zu --i Der nachfolgende Operator i--i dekrementiert, aber den Wert before the ergibt dekrementieren. Ihre Konsole kann dies demonstrieren:

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

    [5, 5, 4]

    Bei der letzten Iteration war i zuvor 1 und der Ausdruck i-- Ändert ihn in , ergibt aber tatsächlich - 1 (wahr), und so ist die Bedingung erfüllt. Bei der nächsten Iteration ändert sich i-- i in - 1, ergibt jedoch (Falsey), wodurch die Ausführung sofort unterbrochen wird aus dem Boden der Schleife.

    In der traditionellen Forwards for-Schleife sind i++ Und ++i Austauschbar (wie Douglas Crockford betont). In der umgekehrten for-Schleife müssen wir jedoch bei i-- Bleiben, wenn wir das Element bei Index 0 verarbeiten möchten, da unser Dekrement auch unser Bedingungsausdruck ist.


Trivia

Einige Leute mögen es, einen kleinen Pfeil in der umgekehrten for Schleife zu zeichnen und mit einem Augenzwinkern zu beenden:

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

Dank geht an WYL, um mir die Vor- und Nachteile der umgekehrten for-Schleife zu zeigen.

99
joeytwiddle

Einige Sprachen im C - Stil verwenden foreach, um Aufzählungen zu durchlaufen. In JavaScript geschieht dies mit der for..in-Schleifenstruktur :

var index,
    value;
for (index in obj) {
    value = obj[index];
}

Es gibt einen Haken. for..in durchläuft jedes der Aufzählungselemente des Objekts und die Mitglieder des Prototyps. Um das Lesen von Werten zu vermeiden, die durch den Prototyp des Objekts vererbt werden, prüfen Sie einfach, ob die Eigenschaft zum Objekt gehört:

for (i in obj) {
    if (obj.hasOwnProperty(i)) {
        //do stuff
    }
}

Darüber hinaus hat ECMAScript 5 eine Methode forEach zu Array.prototype hinzugefügt, die zum Auflisten eines Arrays mithilfe eines Calbacks verwendet werden kann (die Polyfill-Datei befindet sich in den Dokumenten und kann daher für ältere Browser verwendet werden):

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

Es ist wichtig zu wissen, dass Array.prototype.forEach nicht abbricht, wenn der Rückruf false zurückgibt. jQuery und Underscore.js stellen ihre eigenen Variationen von each bereit, um Schleifen bereitzustellen, die kurzgeschlossen werden können.

75
zzzzBov

Wenn Sie ein Array durchlaufen möchten, verwenden Sie die dreiteilige Standardvariable for.

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

Sie können einige Leistungsoptimierungen erhalten, indem Sie myArray.length zwischenspeichern oder rückwärts iterieren.

34
Quentin

Ich weiß, dass dies ein alter Beitrag ist, und es gibt bereits so viele großartige Antworten. Für ein bisschen mehr Vollständigkeit dachte ich, ich würde eine andere mit AngularJS einfügen. Das gilt natürlich nur, wenn Sie Angular verwenden. Natürlich möchte ich es trotzdem sagen.

angular.forEach nimmt 2 Argumente und ein optionales drittes Argument an. Das erste Argument ist das zu iterierende Objekt (Array), das zweite Argument ist die Iterator-Funktion und das optionale dritte Argument ist der Objektkontext (grundsätzlich innerhalb der Schleife als "this" bezeichnet).

Es gibt verschiedene Möglichkeiten, die forEach-Schleife zu verwenden. Das einfachste und wahrscheinlich am meisten verwendete ist

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

Eine andere Möglichkeit, um Elemente von einem Array in ein anderes zu kopieren, ist die

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);

Sie müssen das jedoch nicht tun, Sie können einfach Folgendes tun und entspricht dem vorherigen Beispiel:

angular.forEach(temp, function(item) {
    temp2.Push(item);
});

Jetzt gibt es Vor-und Nachteile der Verwendung der angular.forEach-Funktion im Gegensatz zu der in Vanilla-gewürzten for-Schleife.

Pros

  • Einfache Lesbarkeit
  • Einfache Beschreibbarkeit
  • Falls verfügbar, verwendet angular.forEach die ES5-forEach-Schleife. Jetzt werde ich im Cons-Abschnitt effizienter arbeiten, da die forEach-Schleifen viel langsamer sind als die for-Schleifen. Ich erwähne dies als Profi, weil es schön ist, konsequent und standardisiert zu sein.

Betrachten Sie die folgenden 2 geschachtelten Schleifen, die genau dasselbe tun. Nehmen wir an, wir haben 2 Arrays von Objekten und jedes Objekt enthält ein Array von Ergebnissen, von denen jedes eine Value-Eigenschaft hat, die eine Zeichenfolge ist (oder was auch immer). Nehmen wir an, wir müssen jedes Ergebnis durchlaufen und wenn sie gleich sind, dann führen Sie eine Aktion aus: 

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
        }
    }
}

Zugegeben, dies ist ein sehr einfaches hypothetisches Beispiel, aber ich habe mit dem zweiten Ansatz dreifach eingebettete Schleifen geschrieben, und es war sehr schwer zu lesen und zu schreiben.

Cons

  • Effizienz angular.forEach und die native forEach sind beide so sehr langsamer als die normale for-Schleife .... ungefähr 90% langsamer . Für große Datensätze ist es daher am besten, sich an die native for-Schleife zu halten.
  • Keine Unterbrechung, Fortsetzung oder Rückgabe der Unterstützung. continue wird tatsächlich von " accident " unterstützt, um in einem angular.forEach fortzufahren, fügen Sie einfach eine return;-Anweisung in die Funktion wie angular.forEach(array, function(item) { if (someConditionIsTrue) return; }); ein, die dazu führt, dass die Funktion für diese Iteration nicht ausgeführt wird. Dies ist auch auf die Tatsache zurückzuführen, dass die native forEach keine Unterbrechung oder Fortsetzung unterstützt.

Ich bin sicher, dass es auch andere Vor-und Nachteile gibt, und bitte fügen Sie alle hinzu, die Sie für richtig halten. Unterm Strich halte ich das Gefühl, wenn Sie Effizienz benötigen, bleiben Sie nur bei der nativen for-Schleife für Ihre Schleifenanforderungen. Wenn Ihre Datasets jedoch kleiner sind und eine gewisse Effizienz in Kauf genommen werden kann, um Lesbarkeit und Beschreibbarkeit zu erhalten, werfen Sie auf jeden Fall einen angular.forEach in diesen bösen Jungen.

28
user2359695

Wenn es Ihnen nichts ausmacht, das Array zu leeren:

var x;

while(x = y.pop()){ 

    alert(x); //do something 

}

x enthält den letzten Wert von y und wird aus dem Array entfernt. Sie können auch shift() verwenden, wodurch das erste Element aus y ausgegeben und entfernt wird.

27
gaby de wilde

Eine forEach Implementierung ( siehe in 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
  }
);
27
nmoliveira

Eine einfache Lösung wäre jetzt die Verwendung der Bibliothek underscore.js . Es bietet viele nützliche Tools wie each und delegiert den Job automatisch an die native forEach, falls verfügbar.

Ein CodePen-Beispiel Wie es funktioniert, ist:

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

Siehe auch

24
Micka

Es gibt drei Implementierungen von foreach in jQuery wie folgt.

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
24
Rajesh Paul

Wahrscheinlich ist die for(i = 0; i < array.length; i++)-Schleife nicht die beste Wahl. Warum? Wenn du das hast:

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

Die Methode ruft von array[0] bis array[2] auf. Erstens referenziert dies zuerst Variablen, die Sie nicht einmal haben, zweitens würden Sie die Variablen nicht im Array haben, und drittens macht dies den Code fetter. Schau mal, es ist was ich benutze:

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

Und wenn Sie möchten, dass es sich um eine Funktion handelt, können Sie Folgendes tun:

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

Wenn Sie brechen wollen, etwas mehr Logik:

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

Beispiel:

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

Es gibt zurück:

//Hello
//World
//!!!
22

Ab ES6:

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

Dabei of vermeidet die mit in verknüpften Eigenheiten und lässt sie wie die for-Schleife einer anderen Sprache funktionieren, und let bindet i innerhalb der Schleife und nicht innerhalb der Funktion.

Die geschweiften Klammern ({}) können weggelassen werden, wenn es nur einen Befehl gibt (z. B. im obigen Beispiel).

21
Zaz

Dies ist ein Iterator für eine Liste mit wenig Sparen, bei der der Index bei 0 beginnt. Dies ist das typische Szenario, wenn document.getElementsByTagName oder document.querySelectorAll verwendet wird.

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;  

Anwendungsbeispiele:

Beispiel 1

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

Beispiel # 2

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

Jedes p-Tag erhält class="blue"

Beispiel # 3

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

Jedes zweite p-Tag erhält class="red">

Beispiel # 4

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

Und schließlich werden die ersten 20 blauen p-Tags in grün geändert

Vorsicht bei der Verwendung von Zeichenfolge als Funktion: Die Funktion wird außerhalb des Kontextes erstellt und sollte nur verwendet werden, wenn Sie sicher sind, dass der Bereich der Variablen sicher ist. Andernfalls sollten Sie Funktionen besser übergeben, bei denen das Scoping intuitiver ist.

17
Tim

Es gibt keine for each-Schleife in nativem JavaScript . Sie können entweder Bibliotheken verwenden, um diese Funktionalität zu erhalten (ich empfehle Underscore.js ), verwenden Sie eine einfache for in-Schleife.

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

Beachten Sie jedoch, dass es Gründe geben kann, eine noch einfachere for-Schleife zu verwenden (siehe Stapelüberlauf-Frage Warum ist die Verwendung von "for ... in" mit Array-Iteration eine schlechte Idee?)

var instance;
for (var i=0; i < objects.length; i++) {
    var instance = objects[i];
    ...
}
17
joidegn

Es gibt ein paar Möglichkeiten, um ein Array in JavaScript zu durchlaufen, wie folgt:

für - es ist das häufigste. Vollständiger Codeblock für die Schleife

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 - Schleife, wenn eine Bedingung erfüllt ist. Es scheint die schnellste Schleife zu sein

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

do/while - Durchläuft auch einen Codeblock, solange die Bedingung wahr ist, mindestens einmal ausgeführt

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

Funktionale Schleifen - forEach, map, filter, auch reduce (sie durchlaufen die Funktion, werden jedoch verwendet, wenn Sie etwas mit Ihrem Array tun müssen, usw.).

// 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>

Weitere Informationen und Beispiele zur funktionalen Programmierung von Arrays finden Sie im Blogbeitrag Funktionale Programmierung in JavaScript: Zuordnen, Filtern und Verkleinern.

16
Alireza

ECMAScript5 (die Version auf Javascript), um mit Arrays zu arbeiten.

forEach - Durchläuft jedes Element im Array und führt Sie mit jedem Element aus, was Sie benötigen.

['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

In diesem Fall ist der Betrieb des Arrays mit einer eingebauten Funktion interessanter.

map - Erstellt ein neues Array mit dem Ergebnis der Rückruffunktion. Diese Methode eignet sich gut, wenn Sie die Elemente Ihres Arrays formatieren müssen.

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

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

verkleinern - Wie der Name sagt, wird das Array auf einen einzelnen Wert reduziert, indem die angegebene Funktion im currenct-Element übergeben wird und das Ergebnis der vorherigen Ausführung übergeben wird.

[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

alle - Gibt "true" oder "false" zurück, wenn alle Elemente des Arrays den Test in der Rückruffunktion bestehen.

// 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 - Sehr ähnlich zu jedem, außer dass filter ein Array mit den Elementen zurückgibt, die true für die angegebene Funktion zurückgeben.

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

// Output: [2,4,6]

Hoffe das wird nützlich sein.

14
Anil Kumar Arya

Es gibt keine eingebaute Fähigkeit, in forEach einzubrechen. Um die Ausführung zu unterbrechen, verwenden Sie den Array#some wie folgt:

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

Dies funktioniert, weil some true zurückgibt, sobald einer der in Array-Reihenfolge ausgeführten Callbacks true zurückgibt, wodurch die Ausführung des Restes kurzgeschlossen wird. Originalantwort Siehe Array-Prototyp für einige

14

Ich möchte dies auch als Komposition einer umgekehrten Schleife und als Antwort oben für jemanden hinzufügen, der auch diese Syntax möchte.

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

Pros:

Der Vorteil dabei: Sie haben die Referenz bereits im ersten Like, die später nicht mit einer anderen Zeile deklariert werden muss. Dies ist praktisch, wenn Sie das Objektarray durchlaufen.

Nachteile:

Dies wird unterbrochen, wenn der Verweis falsch ist (falscher Wert usw.). Es kann jedoch als Vorteil genutzt werden. Es würde jedoch das Lesen ein wenig schwieriger machen. Und je nach Browser kann es "nicht" optimiert werden, um schneller als der ursprüngliche zu arbeiten.

jQuery-Methode mit $.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];
10
DanFromGermany

Ein Weg, der Ihrer Idee am nächsten kommt, wäre die Verwendung von Array.forEach(), die eine Clojure-Funktion akzeptiert, die für jedes Element des Arrays ausgeführt wird.

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

Ein anderer praktikabler Weg wäre die Verwendung von Array.map(), die auf dieselbe Weise funktioniert, aber auch mutates für jedes Element und es wie folgt zurückgibt:

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

console.log(myArray); // [2, 3, 4]

Verwenden von Schleifen mit ES6 Destrukturierung und Spread-Operator

Die Umstrukturierung und die Verwendung des Spread-Operators haben sich für Neueinsteiger von ES6 als von Menschen lesbarer/ästhetischer als recht nützlich erwiesen, auch wenn einige Javascript-Veteranen dies als unordentlich ansehen, Junioren oder andere Personen dies für nützlich halten.

In den folgenden Beispielen werden for...of Anweisung und .forEach Methode verwendet.

Die Beispiele 6, 7 und 8 können mit beliebigen Funktionsschleifen wie .map, .filter, .reduce, .sort, .every, .some verwendet werden. Weitere Informationen zu diesen Methoden finden Sie unter Array Object .

Beispiel 1: normale for...of-Schleife - hier keine Tricks.

let arrSimple = ['a', 'b', 'c'];

for (let letter of arrSimple) {
  console.log(letter);
}

Beispiel 2: Wörter in Zeichen aufteilen

let arrFruits = ['Apple', 'orange', 'banana'];

for (let [firstLetter, ...restOfTheWord] of arrFruits) {
  // Create a shallow copy using the spread operator
  let [lastLetter] = [...restOfTheWord].reverse();
  console.log(firstLetter, lastLetter, restOfTheWord);

}

Beispiel 3: Looping mit einer key und value 

// let arrSimple = ['a', 'b', 'c'];

// Instead of keeping an index in `i` as per example `for(let i = 0 ; i<arrSimple.length;i++)`
// this example will use a multi-dimensional array of the following format type: 
// `arrWithIndex: [number, string][]`

let arrWithIndex = [
  [0, 'a'],
  [1, 'b'],
  [2, 'c'],
];

// Same thing can be achieved using `.map` method
// let arrWithIndex = arrSimple.map((i, idx) => [idx, i]);

// Same thing can be achieved using `Object.entries`
// NOTE: `Object.entries` method doesn't work on internet Explorer unless it's polyfilled
// let arrWithIndex = Object.entries(arrSimple);

for (let [key, value] of arrWithIndex) {
  console.log(key, value);
}

Beispiel 4: Holen Sie Objekteigenschaften inline

let arrWithObjects = [{
    name: 'Jon',
    age: 32
  },
  {
    name: 'Elise',
    age: 33
  }
];

for (let { name, age: aliasForAge } of arrWithObjects) {
  console.log(name, aliasForAge);
}

Beispiel 5: Holen Sie sich tiefe Objekteigenschaften von dem, was Sie brauchen

let arrWithObjectsWithArr = [{
    name: 'Jon',
    age: 32,
    tags: ['driver', 'chef', 'jogger']
  },
  {
    name: 'Elise',
    age: 33,
    tags: ['best chef', 'singer', 'dancer']
  }
];

for (let { name, tags: [firstItemFromTags, ...restOfTags] } of arrWithObjectsWithArr) {
  console.log(name, firstItemFromTags, restOfTags);
}

Beispiel 6: wird Beispiel 3 verwendet mit .forEach

let arrWithIndex = [
  [0, 'a'],
  [1, 'b'],
  [2, 'c'],
];

// Not to be confused here, `forEachIndex` is the real index
// `mappedIndex` was created by "another user", so you can't really trust it

arrWithIndex.forEach(([mappedIndex, item], forEachIndex) => {
  console.log(forEachIndex, mappedIndex, item);
});

Beispiel 7: wird Beispiel 4 verwendet mit .forEach

let arrWithObjects = [{
    name: 'Jon',
    age: 32
  },
  {
    name: 'Elise',
    age: 33
  }
];
// NOTE: Destructuring objects while using shorthand functions 
// are required to be surrounded by parenthesis
arrWithObjects.forEach( ({ name, age: aliasForAge }) => {
  console.log(name, aliasForAge)
});

Beispiel 8: wird Beispiel 5 verwendet mit .forEach

let arrWithObjectsWithArr = [{
    name: 'Jon',
    age: 32,
    tags: ['driver', 'chef', 'jogger']
  },
  {
    name: 'Elise',
    age: 33,
    tags: ['best chef', 'singer', 'dancer']
  }
];

arrWithObjectsWithArr.forEach(({
  name,
  tags: [firstItemFromTags, ...restOfTags]
}) => {
  console.log(name, firstItemFromTags, restOfTags);
});

6
darklightcode

Die Lambda-Syntax funktioniert normalerweise nicht in IE 10 oder darunter.

Ich benutze normalerweise die

[].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);
});
5
Murtuza Husain

Sie können forEach wie folgt anrufen:

let Array = [1,3,2];

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

element hat den Wert jedes Index von 0 bis zur Länge des Arrays.

Ausgabe:

1    
3    
2

Erklärung:

forEach ist in der Prototypenklasse. Sie können dies auch als theArray.prototype.forEach (...) bezeichnen.

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

Sie können auch ein Array wie folgt ändern:

for(let i=0;i<theArray.length;i++){
  console.log(i); //i will have the value of each index
}
4
Nouman Dilshad

wenn Sie ein Array von Objekten mit Pfeilfunktion durchlaufen möchten:

let arr=[{name:'john',age:50},{name:'clark',age:19},{name:'mohan',age:26}];

arr.forEach((person)=>{
  console.log('i am '+person.name+' and i am '+person.age+ ' old');
})
3
subhashish negi

Zusammenfassung:

Beim Durchlaufen eines Arrays können wir oft eines der folgenden Ziele erreichen:

  1. Wir möchten über das Array iterieren und ein neues Array erstellen:

    Array.prototype.map 

  2. Wir möchten über das Array iterieren und erstellen kein neues Array:

    Array.prototype.forEach 

    for..of Schleife

In JS gibt es viele Möglichkeiten, diese beiden Ziele zu erreichen. Einige sind jedoch sinnvoller als andere. Nachfolgend finden Sie einige häufig verwendete Methoden (die gängigsten imo-Methoden), um eine Array-Iteration in Javascript durchzuführen.

Neues Array erstellen: Map

map() ist eine Funktion in Array.prototype, die jedes Element eines Arrays transformieren kann und dann ein new -Array zurückgibt. map() nimmt eine Rückruffunktion als Argument und arbeitet auf folgende Weise:

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

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

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

Der Rückruf, den wir als Argument an map() übergeben haben, wird für jedes Element ausgeführt. Dann wird ein Array zurückgegeben, das die gleiche Länge wie das ursprüngliche Array hat. In diesem neuen Array-Element wird die Callback-Funktion als Argument an map() übergeben.

Der Unterschied zwischen map und anderen Schleifenmechanismen wie forEach und einer for..of-Schleife besteht darin, dassmap als neues Array zurückgegeben wird und das alte Array intakt bleibt (es sei denn, Sie manipulieren es mit splice

Beachten Sie auch, dass der Callback der Funktion map als zweites Argument die Indexnummer der aktuellen Iteration bereitstellt. Außerdem liefert das dritte Argument das Array, für das map aufgerufen wurde. Manchmal können diese Eigenschaften sehr nützlich sein.

Schleife mit forEach

forEach ist eine Funktion, die sich auf Array.prototype befindet und eine Rückruffunktion als Argument verwendet. Sie führt dann diese Callback-Funktion für jedes Element im Array aus. Im Gegensatz zur Funktion map() gibt die Funktion forEach nichts zurück (undefined). Zum Beispiel:

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);

Genau wie die map-Funktion liefert der forEach-Callback als zweites Argument die Indexnummer der aktuellen Iteration. Das dritte Argument gibt auch das Array an, für das forEach aufgerufen wurde. 

Elemente mit for..of durchlaufen

Die for..of-Schleife durchläuft jedes Element eines Arrays (oder jedes anderen iterierbaren Objekts). Es funktioniert auf folgende Weise:

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

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

Im obigen Beispiel steht element für ein Array-Element und arr ist das Array, das wir schleifen möchten. Nicht dass der Name element willkürlich ist und wir hätten einen anderen Namen wie 'el' oder etwas mehr Deklaratives wählen können, wenn dies zutrifft. 

Verwechseln Sie die for..in-Schleife nicht mit der for..of-Schleife. for..in durchläuft alle aufzählbaren Eigenschaften des Arrays, während die for..of-Schleife nur die Array-Elemente durchläuft. Zum Beispiel:

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);
}

2

Wenn Sie ein großes Array haben, sollten Sie iterators verwenden, um eine gewisse Effizienz zu erzielen. Iteratoren sind eine Eigenschaft bestimmter JavaScript-Sammlungen (wie Map , Set , String , Array ). Gerade for..of verwendet iterator unter der Haube.

Iteratoren verbessern die Effizienz, indem Sie die Elemente in einer Liste nacheinander konsumieren lassen, als ob sie ein Stream wären. Das Besondere an einem Iterator ist das Durchlaufen einer Sammlung. Andere Schleifen müssen die gesamte Sammlung nach vorne laden, um darüber zu iterieren, während ein Iterator nur die aktuelle Position in der Sammlung kennen muss. 

Sie können auf das aktuelle Element zugreifen, indem Sie die next-Methode des Iterators aufrufen. Die nächste Methode gibt die value des aktuellen Elements und eine boolean zurück, um anzuzeigen, wann Sie das Ende der Sammlung erreicht haben. Das folgende Beispiel zeigt das Erstellen eines Iterators aus einem Array. 

Wandeln Sie Ihr reguläres Array mithilfe der Methode " values() " in einen Iterator um: 

    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());

Sie können Ihr reguläres Array auch in Iterator transformieren, indem Sie Symbol.iterator wie folgt verwenden: 

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());

Sie können auch Ihre reguläre array in eine iterator wie folgt umwandeln: 

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}

HINWEIS

  • Iteratoren sind in der Natur erschöpfbar. 
  • Objekte sind standardmäßig nicht iterable. Verwenden Sie for..in in diesem Fall, da anstelle von Werten mit Schlüsseln gearbeitet wird.

Sie können mehr über iteration protocolhier lesen. 

1
BlackBeard
var a = ["car", "bus", "truck"]
a.forEach(function(item, index) {
    console.log("Index" + index);
    console.log("Element" + item);
})
1
John

// Looping through arrays using foreach  ES6 way

var data = new Array(1,2,3,4,5);
data.forEach((val,index) => {
    console.log("index :",index); // index
	console.log("value :", val); // value
});

0
arul prince

Sie können die forEach () - API (bereitgestellt von Javascript) verwenden, die eine Funktion als Rückruf akzeptiert und einmal für jedes im Array vorhandene Element ausgeführt wird.

https://fullstackgeek.blogspot.com/2019/01/arrays-in-javascript-part-2.html

0
Ayush Jain

Ich komme aus Python und fand diesen Weg viel klarer.
das Array ist das Array, die Instanz das Element des Arrays

for(let instance of theArray)
{
    console.log("The instance",instance);
}

oder

for( instance in theArray)
{
  console.log("The instance",instance);
}

vergleichen mit:

theArray.forEach(function(instance) {
    console.log(instance);
});

aber am Ende des Tages machen beide dasselbe

0
Peko Chan

Wenn Sie Ihren Code auf funktionale Weise beibehalten möchten, verwenden Sie map:

theArray.map(instance => do_something);

Auf diese Weise generieren Sie ein neues Array für den zukünftigen Betrieb und überspringen alle unerwünschten Nebeneffekte.

0
alejoko

Wenn Sie forEach() verwenden möchten, sieht es aus wie - 

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

Wenn Sie for() verwenden möchten, sieht es aus wie - 

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