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.
TL; DR
for-in
nur, wenn Sie es mit Sicherheitsvorkehrungen verwenden oder zumindest wissen, warum es Sie beißen könnte.Ihre besten Wetten sind normalerweise
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:
Sie haben drei Möglichkeiten in ECMAScript 5 ("ES5"), der derzeit am meisten unterstützten Version, und zwei weitere in ECMAScript 2015 ( "ES2015", "ES6"):
forEach
und verwandte (ES5 +)for
-Schleifefor-in
richtig for-of
(benutze implizit einen Iterator) (ES2015 +)Einzelheiten:
forEach
und verwandteIn 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)for
-SchleifeManchmal 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.
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:
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:
Dass das Objekt seine eigene Eigenschaft unter diesem Namen hat (nicht eine, die es von seinem Prototyp erbt), und
Dass der Schlüssel ausschließlich aus Dezimalstellen besteht (z. B. normale Zeichenfolgenform, keine wissenschaftliche Notation), und
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);
});
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.
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.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?
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:
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`
});
Benutze eine einfache for
-Schleife
Offensichtlich gilt eine einfache for
-Schleife für arrayähnliche Objekte.
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.
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.
Verwenden Sie explizit einen Iterator (ES2015 +)
Siehe # 4, wir müssen sehen, wie Iteratoren ablaufen.
In anderen Fällen möchten Sie möglicherweise ein Array-ähnliches Objekt in ein echtes Array konvertieren. Das ist überraschend einfach:
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.
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")];
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;
});
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.)
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:
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.
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].
}
Ich denke, die reverse for-Schleife verdient eine Erwähnung hier:
for (var i = array.length; i--; ) {
// process array[i]
}
len
-Variable deklarieren oder bei jeder Iteration mit array.length
Vergleichen, was möglicherweise eine winzige Optimierung darstellt.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 .forEach()
und an ES6's for ... of
.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!
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:
for
und while
Schleifen verbirgt.)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 .)
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.
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.
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.
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.
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
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
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.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.
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.
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
}
);
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)
{
...
});
Array.prototype.forEach()
.for each (variable in object)
als Teil des ECMA-357 ( EAX ) - Standards veraltet ist.for (variable of object)
als Teil des Harmony-Vorschlags (ECMAScript 6) zu iterieren.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
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
//!!!
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).
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.
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];
...
}
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.
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.
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
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];
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);
});
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);
});
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
}
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');
})
Beim Durchlaufen eines Arrays können wir oft eines der folgenden Ziele erreichen:
Wir möchten über das Array iterieren und ein neues Array erstellen:
Array.prototype.map
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.
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.
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.
for..of
durchlaufenDie 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);
}
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:
iterable
. Verwenden Sie for..in
in diesem Fall, da anstelle von Werten mit Schlüsseln gearbeitet wird.Sie können mehr über iteration protocol
hier lesen.
var a = ["car", "bus", "truck"]
a.forEach(function(item, index) {
console.log("Index" + index);
console.log("Element" + item);
})
// 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
});
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
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
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.
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);
}