Schleifen und Iteration
Schleifen bieten eine schnelle und einfache Möglichkeit, etwas wiederholt auszuführen. Dieses Kapitel des JavaScript-Leitfadens führt die verschiedenen Iterationsanweisungen ein, die in JavaScript verfügbar sind.
Sie können sich eine Schleife als eine computerisierte Version des Spiels vorstellen, bei dem Sie jemandem sagen, er solle X Schritte in eine Richtung und dann Y Schritte in eine andere Richtung machen. Zum Beispiel könnte die Idee "Gehe fünf Schritte nach Osten" so als Schleife ausgedrückt werden:
for (let step = 0; step < 5; step++) {
// Runs 5 times, with values of step 0 through 4.
console.log("Walking east one step");
}
Es gibt viele verschiedene Arten von Schleifen, aber sie alle tun im Wesentlichen dasselbe: Sie wiederholen eine Aktion eine bestimmte Anzahl von Malen. (Beachten Sie, dass es möglich ist, dass diese Anzahl null sein könnte!)
Die verschiedenen Schleifenmechanismen bieten unterschiedliche Möglichkeiten, den Start- und Endpunkt der Schleife zu bestimmen. Es gibt verschiedene Situationen, die durch eine Art von Schleife besser bedient werden als durch andere.
Die in JavaScript bereitgestellten Anweisungen für Schleifen sind:
for-Anweisung
Eine for-Schleife wiederholt sich, bis eine angegebene Bedingung als falsch ausgewertet wird. Die JavaScript-for-Schleife ist der for-Schleife in Java und C ähnlich.
Eine for-Anweisung sieht wie folgt aus:
for (initialization; condition; afterthought)
statement
Wenn eine for-Schleife ausgeführt wird, passiert Folgendes:
- Der Initialisierungsausdruck
initialization, falls vorhanden, wird ausgeführt. Dieser Ausdruck initialisiert normalerweise einen oder mehrere Schleifenzähler, aber die Syntax erlaubt einen Ausdruck beliebiger Komplexität. Dieser Ausdruck kann auch Variablen deklarieren. - Der Ausdruck
conditionwird ausgewertet. Wenn der Wert vonconditionwahr ist, werden die Schleifenanweisungen ausgeführt. Andernfalls endet diefor-Schleife. (Wenn dercondition-Ausdruck vollständig weggelassen wird, wird die Bedingung als wahr angenommen.) - Die
statementwird ausgeführt. Um mehrere Anweisungen auszuführen, verwenden Sie eine Blockanweisung ({ }), um diese Anweisungen zu gruppieren. - Falls vorhanden, wird der Aktualisierungsausdruck
afterthoughtausgeführt. - Die Steuerung kehrt zu Schritt 2 zurück.
Beispiel
Im untenstehenden Beispiel enthält die Funktion eine for-Anweisung, die die Anzahl der ausgewählten Optionen in einer Scrollliste (ein <select>-Element, das Mehrfachauswahlen zulässt) zählt.
HTML
<form name="selectForm">
<label for="musicTypes"
>Choose some music types, then click the button below:</label
>
<select id="musicTypes" name="musicTypes" multiple>
<option selected>R&B</option>
<option>Jazz</option>
<option>Blues</option>
<option>New Age</option>
<option>Classical</option>
<option>Opera</option>
</select>
<button id="btn" type="button">How many are selected?</button>
</form>
JavaScript
Hier deklariert die for-Anweisung die Variable i und initialisiert sie mit 0. Sie überprüft, ob i kleiner als die Anzahl der Optionen im <select>-Element ist, führt die nachfolgende if-Anweisung aus und erhöht i nach jedem Durchlauf der Schleife um 1.
function countSelected(selectObject) {
let numberSelected = 0;
for (let i = 0; i < selectObject.options.length; i++) {
if (selectObject.options[i].selected) {
numberSelected++;
}
}
return numberSelected;
}
const btn = document.getElementById("btn");
btn.addEventListener("click", () => {
const musicTypes = document.selectForm.musicTypes;
console.log(`You have selected ${countSelected(musicTypes)} option(s).`);
});
do...while-Anweisung
Die do...while-Anweisung wiederholt sich, bis eine angegebene Bedingung als falsch bewertet wird.
Eine do...while-Anweisung sieht wie folgt aus:
do
statement
while (condition);
statement wird immer einmal ausgeführt, bevor die Bedingung überprüft wird. (Um mehrere Anweisungen auszuführen, verwenden Sie eine Blockanweisung ({ }), um diese Anweisungen zu gruppieren.)
Wenn condition wahr ist, wird die Anweisung erneut ausgeführt. Am Ende jeder Ausführung wird die Bedingung überprüft. Wenn die Bedingung false ist, stoppt die Ausführung und die Steuerung wird an die Anweisung nach do...while übergeben.
Beispiel
Im folgenden Beispiel wiederholt sich die do-Schleife mindestens einmal und wird erneut ausgeführt, bis i nicht mehr kleiner als 5 ist.
let i = 0;
do {
i += 1;
console.log(i);
} while (i < 5);
while-Anweisung
Eine while-Anweisung führt ihre Anweisungen aus, solange eine angegebene Bedingung als true bewertet wird. Eine while-Anweisung sieht wie folgt aus:
while (condition)
statement
Wenn die condition false wird, hört statement innerhalb der Schleife auf zu laufen und die Steuerung wird an die Anweisung übergeben, die der Schleife folgt.
Der Bedingungstest erfolgt bevor die statement in der Schleife ausgeführt wird. Wenn die Bedingung true zurückgibt, wird statement ausgeführt und die condition wird erneut getestet. Wenn die Bedingung false zurückgibt, stoppt die Ausführung, und die Steuerung wird an die Anweisung übergeben, die while folgt.
Um mehrere Anweisungen auszuführen, verwenden Sie eine Blockanweisung ({ }), um diese Anweisungen zu gruppieren.
Beispiel 1
Die folgende while-Schleife wird so lange iteriert, wie n kleiner als 3 ist:
let n = 0;
let x = 0;
while (n < 3) {
n++;
x += n;
}
Bei jedem Durchlauf erhöht die Schleife n und addiert diesen Wert zu x. Daher nehmen x und n die folgenden Werte an:
- Nach dem ersten Durchgang:
n=1undx=1 - Nach dem zweiten Durchgang:
n=2undx=3 - Nach dem dritten Durchgang:
n=3undx=6
Nach dem Abschluss des dritten Durchgangs ist die Bedingung n < 3 nicht mehr true, sodass die Schleife endet.
Beispiel 2
Vermeiden Sie Endlosschleifen. Stellen Sie sicher, dass die Bedingung in einer Schleife irgendwann false wird - andernfalls wird die Schleife niemals enden! Die Anweisungen in der folgenden while-Schleife werden unendlich oft ausgeführt, da die Bedingung niemals false wird:
// Infinite loops are bad!
while (true) {
console.log("Hello, world!");
}
labeled-Anweisung
Eine label bietet einer Anweisung einen Bezeichner, mit dem Sie in anderen Teilen Ihres Programms darauf verweisen können. Beispielsweise können Sie ein Label verwenden, um eine Schleife zu identifizieren, und dann die break- oder continue-Anweisungen verwenden, um anzugeben, ob ein Programm die Schleife unterbrechen oder seine Ausführung fortsetzen soll.
Die Syntax der labeled-Anweisung sieht wie folgt aus:
label:
statement
Der Wert von label kann jeder JavaScript-Bezeichner sein, der kein reserviertes Wort ist. Die statement, die Sie mit einem Label identifizieren, kann jede Anweisung sein. Für Beispiele zur Verwendung von labeled-Anweisungen siehe die weiter unten stehenden Beispiele für break und continue.
break-Anweisung
Verwenden Sie die break-Anweisung, um eine Schleife, einen switch oder in Verbindung mit einer labeled-Anweisung zu beenden.
- Wenn Sie
breakohne Label verwenden, beendet es sofort die innerste, umschließendewhile-,do-while-,for- oderswitch-Anweisung und überträgt die Steuerung auf die nachfolgende Anweisung. - Wenn Sie
breakmit einem Label verwenden, beendet es die angegebene labeled-Anweisung.
Die Syntax der break-Anweisung sieht wie folgt aus:
break;
break label;
- Die erste Form der Syntax beendet die innerste, umschließende Schleife oder
switch. - Die zweite Form der Syntax beendet die angegebene, umschließende labeled-Anweisung.
Beispiel 1
Das folgende Beispiel iteriert durch die Elemente in einem Array, bis es den Index eines Elements findet, dessen Wert theValue ist:
for (let i = 0; i < a.length; i++) {
if (a[i] === theValue) {
break;
}
}
Beispiel 2: Unterbrechen zu einem Label
let x = 0;
let z = 0;
labelCancelLoops: while (true) {
console.log("Outer loops:", x);
x += 1;
z = 1;
while (true) {
console.log("Inner loops:", z);
z += 1;
if (z === 10 && x === 10) {
break labelCancelLoops;
} else if (z === 10) {
break;
}
}
}
continue-Anweisung
Die continue-Anweisung kann verwendet werden, um eine while, do-while, for oder label-Anweisung neu zu starten.
- Wenn Sie
continueohne Label verwenden, beendet es die aktuelle Iteration der innersten, umschließendenwhile-,do-while- oderfor-Anweisung und setzt die Ausführung der Schleife mit der nächsten Iteration fort. Im Gegensatz zurbreak-Anweisung beendetcontinuedie Ausführung der Schleife nicht vollständig. In einerwhile-Schleife wird zur Bedingung zurückgesprungen. In einerfor-Schleife wird zumincrement-expressiongesprungen. - Wenn Sie
continuemit einem Label verwenden, bezieht es sich auf die Schleifenanweisung, die mit diesem Label identifiziert ist.
Die Syntax der continue-Anweisung sieht wie folgt aus:
continue;
continue label;
Beispiel 1
Das folgende Beispiel zeigt eine while-Schleife mit einer continue-Anweisung, die ausgeführt wird, wenn der Wert von i gleich 3 ist. Somit nimmt n die Werte 1, 3, 7 und 12 an.
let i = 0;
let n = 0;
while (i < 5) {
i++;
if (i === 3) {
continue;
}
n += i;
console.log(n);
}
// Logs:
// 1 3 7 12
Wenn Sie die continue; auskommentieren, würde die Schleife bis zum Ende laufen und Sie würden 1,3,6,10,15 sehen.
Beispiel 2
Eine Anweisung, die mit checkIandJ beschriftet ist, enthält eine Anweisung, die mit checkJ beschriftet ist. Wenn continue angetroffen wird, beendet das Programm die aktuelle Iteration von checkJ und beginnt die nächste Iteration. Bei jedem Mal, wenn continue angetroffen wird, wird checkJ erneut durchlaufen, bis seine Bedingung false zurückgibt. Bei einer Rückgabe von false wird der Rest der checkIandJ-Anweisung abgeschlossen, und checkIandJ wird erneut durchlaufen, bis seine Bedingung false zurückgibt. Bei einer Rückgabe von false wird das Programm bei der Anweisung nach checkIandJ fortgesetzt.
Wenn continue ein Label von checkIandJ hätte, würde das Programm am Anfang der checkIandJ-Anweisung fortfahren.
let i = 0;
let j = 10;
checkIandJ: while (i < 4) {
console.log(i);
i += 1;
checkJ: while (j > 4) {
console.log(j);
j -= 1;
if (j % 2 === 0) {
continue;
}
console.log(j, "is odd.");
}
console.log("i =", i);
console.log("j =", j);
}
for...in-Anweisung
Die for...in-Anweisung iteriert eine angegebene Variable über alle aufzählbaren Eigenschaften eines Objekts. Für jede unterschiedliche Eigenschaft führt JavaScript die angegebenen Anweisungen aus. Eine for...in-Anweisung sieht wie folgt aus:
for (variable in object)
statement
Beispiel
Die folgende Funktion nimmt ein Objekt und den Namen des Objekts als Argument und iteriert dann über alle Eigenschaften des Objekts und gibt eine Zeichenfolge zurück, die die Eigenschaftsnamen und ihre Werte auflistet.
function dumpProps(obj, objName) {
let result = "";
for (const i in obj) {
result += `${objName}.${i} = ${obj[i]}<br>`;
}
result += "<hr>";
return result;
}
Für ein Objekt car mit den Eigenschaften make und model, wäre result:
car.make = Ford car.model = Mustang
Arrays
Obwohl es verlockend sein mag, dies als eine Möglichkeit zu verwenden, um über Array-Elemente zu iterieren, gibt die for...in-Anweisung zusätzlich zu den numerischen Indizes auch den Namen Ihrer benutzerdefinierten Eigenschaften zurück.
Daher ist es besser, eine traditionelle for-Schleife mit einem numerischen Index zu verwenden, wenn Sie über Arrays iterieren, da die for...in-Anweisung über benutzerdefinierte Eigenschaften zusätzlich zu den Array-Elementen iteriert, falls Sie das Array-Objekt ändern (z. B. durch Hinzufügen benutzerdefinierter Eigenschaften oder Methoden).
for...of-Anweisung
Die for...of-Anweisung erstellt eine Schleife, die über iterierbare Objekte (einschließlich Array, Map, Set, arguments-Objekt und so weiter) iteriert und einen benutzerdefinierten Iterationshaken mit Anweisungen aufruft, die für den Wert jeder unterschiedlichen Eigenschaft ausgeführt werden sollen.
for (variable of iterable)
statement
Das folgende Beispiel zeigt den Unterschied zwischen einer for...of-Schleife und einer for...in-Schleife. Während for...in über Eigenschaftsnamen iteriert, iteriert for...of über Eigenschaftswerte:
const arr = [3, 5, 7];
arr.foo = "hello";
for (const i in arr) {
console.log(i);
}
// "0" "1" "2" "foo"
for (const i of arr) {
console.log(i);
}
// Logs: 3 5 7
Die for...of- und for...in-Anweisungen können auch mit Destructuring verwendet werden. Beispielsweise können Sie gleichzeitig über die Schlüssel und Werte eines Objekts mit Object.entries() schleifen.
const obj = { foo: 1, bar: 2 };
for (const [key, val] of Object.entries(obj)) {
console.log(key, val);
}
// "foo" 1
// "bar" 2