Kontrollfluss und Fehlerbehandlung
JavaScript unterstützt eine kompakte Menge von Anweisungen, insbesondere Kontrollflussanweisungen, die Sie nutzen können, um eine hohe Interaktivität in Ihrer Anwendung zu integrieren. Dieses Kapitel bietet einen Überblick über diese Anweisungen.
DasJavaScript-Referenzdokument enthält umfassende Informationen über die in diesem Kapitel behandelten Anweisungen. Das Semikolon (;
) wird verwendet, um Anweisungen in JavaScript-Code zu trennen.
Jeder JavaScript-Ausdruck ist auch eine Anweisung. SieheAusdrücke und Operatoren für vollständige Informationen über Ausdrücke.
Blockanweisung
Die grundlegendste Anweisung ist eineBlockanweisung, die verwendet wird, um Anweisungen zu gruppieren. Der Block wird durch ein Paar geschweifter Klammern begrenzt:
{ statement1; statement2; // … statementN;}
Beispiel
Blockanweisungen werden häufig mit Kontrollflussanweisungen (if
,for
,while
) verwendet.
while (x < 10) { x++;}
Hier ist{ x++; }
die Blockanweisung.
Hinweis:Invar
-deklarierte Variablen sind nicht blockgebunden, sondern sind innerhalb der umschließenden Funktion oder des Skripts gebunden, und die Auswirkungen ihrer Festlegung bestehen über den Block hinaus. Zum Beispiel:
var x = 1;{ var x = 2;}console.log(x); // 2
Dies gibt2
aus, weil dievar x
-Anweisung innerhalb des Blocks im gleichen Gültigkeitsbereich wie dievar x
-Anweisung vor dem Block liegt. (In C oder Java würde der äquivalente Code1
ausgeben.)
Dieser Geltungsbereicheffekt kann gemildert werden, indem manlet
oderconst
verwendet.
Bedingungsanweisungen
Eine Bedingungsanweisung ist eine Gruppe von Befehlen, die ausgeführt werden, wenn eine angegebene Bedingung wahr ist. JavaScript unterstützt zwei Bedingungsanweisungen:if...else
undswitch
.
if...else-Anweisung
Verwenden Sie dieif
-Anweisung, um eine Anweisung auszuführen, wenn eine logische Bedingungtrue
ist. Verwenden Sie die optionaleelse
-Klausel, um eine Anweisung auszuführen, wenn die Bedingungfalse
ist.
Eineif
-Anweisung sieht folgendermaßen aus:
if (condition) { statement1;} else { statement2;}
Hier kann dieBedingung
ein beliebiger Ausdruck sein, der zutrue
oderfalse
auswertet. (SieheBoolean für eine Erklärung dessen, was zutrue
undfalse
ausgewertet wird.)
Wenn dieBedingung
zutrue
ausgewertet wird, wirdAnweisung1
ausgeführt. Andernfalls wirdAnweisung2
ausgeführt.Anweisung1
undAnweisung2
können beliebige Anweisungen sein, einschließlich weiterer geschachtelterif
-Anweisungen.
Sie können auch die Anweisungen mitelse if
kombinieren, um mehrere Bedingungen hintereinander zu testen, wie folgt:
if (condition1) { statement1;} else if (condition2) { statement2;} else if (conditionN) { statementN;} else { statementLast;}
Im Falle mehrerer Bedingungen wird nur die erste logische Bedingung, die zutrue
ausgewertet wird, ausgeführt. Um mehrere Anweisungen auszuführen, gruppieren Sie diese innerhalb einer Blockanweisung ({ /* … */ }
).
Gute Praxis
Im Allgemeinen ist es eine gute Praxis, immer Blockanweisungen zu verwenden—insbesondere beim Schachteln vonif
-Anweisungen:
if (condition) { // Statements for when condition is true // …} else { // Statements for when condition is false // …}
Im Allgemeinen ist es eine gute Praxis, keineif...else
-Anweisung mit einer Zuweisung wiex = y
als Bedingung zu haben:
if (x = y) { // statements here}
In dem seltenen Fall, dass Sie etwas in dieser Art tun möchten, bietet die Dokumentation zuwhile
unterVerwendung einer Zuweisung als Bedingung eine Sektion mit Anleitung zu einem allgemeinen Best-Practice-Syntax, die Sie kennen und befolgen sollten.
Falsy-Werte
Die folgenden Werte werden alsfalse
ausgewertet (auch bekannt alsFalsy Werte):
false
undefined
null
0
NaN
- der leere String (
""
)
Alle anderen Werte—einschließlich aller Objekte—werden alstrue
ausgewertet, wenn sie an eine Bedingungsanweisung übergeben werden.
Hinweis:Verwechseln Sie nicht die primitiven booleschen Wertetrue
undfalse
mit den true- und false-Werten desBoolean
-Objekts!
Zum Beispiel:
const b = new Boolean(false);if (b) { // diese Bedingung wertet zu true aus}if (b == true) { // diese Bedingung wertet zu false aus}
Beispiel
Im folgenden Beispiel gibt die FunktioncheckData
true
zurück, wenn die Anzahl der Zeichen in einemText
-Objekt drei beträgt. Andernfalls zeigt es eine Warnung an und gibtfalse
zurück.
function checkData() { if (document.form1.threeChar.value.length === 3) { return true; } alert( `Enter exactly three characters. ${document.form1.threeChar.value} is not valid.`, ); return false;}
switch-Anweisung
Eineswitch
-Anweisung ermöglicht es einem Programm, einen Ausdruck auszuwerten und zu versuchen, den Wert des Ausdrucks mit einemcase
-Label abzugleichen. Wenn ein Treffer gefunden wird, führt das Programm die zugehörige Anweisung aus.
Eineswitch
-Anweisung sieht folgendermaßen aus:
switch (expression) { case label1: statements1; break; case label2: statements2; break; // … default: statementsDefault;}
JavaScript wertet die oben stehende switch-Anweisung wie folgt aus:
- Das Programm sucht zuerst nach einer
case
-Klausel mit einem Label, das dem Wert des Ausdrucks entspricht, und überträgt dann die Kontrolle auf diese Klausel, indem es die zugehörigen Anweisungen ausführt. - Wenn kein entsprechendes Label gefunden wird, sucht das Programm nach der optionalen
default
-Klausel:- Wenn eine
default
-Klausel gefunden wird, überträgt das Programm die Kontrolle auf diese Klausel und führt die zugehörigen Anweisungen aus. - Wenn keine
default
-Klausel gefunden wird, setzt das Programm die Ausführung bei der Anweisung nach dem Ende vonswitch
fort. - (Der Konvention nach wird die
default
-Klausel als letzte Klausel geschrieben, dies ist jedoch nicht zwingend notwendig.)
- Wenn eine
break-Anweisungen
Die optionalebreak
-Anweisung, die mit jedercase
-Klausel verbunden ist, stellt sicher, dass das Programm dieswitch
-Anweisung nach der Ausführung der übereinstimmenden Anweisung verlässt und dann die Ausführung bei der Anweisung nach demswitch
fortsetzt. Wennbreak
weggelassen wird, setzt das Programm die Ausführung innerhalb derswitch
-Anweisung fort (und wird die Anweisungen unter dem nächstencase
wie auch die nachfolgenden ausführen).
Beispiel
Im folgenden Beispiel wird, wennfruitType
zu"Bananas"
ausgewertet wird, der Wert mitcase "Bananas"
abgeglichen und die zugehörige Anweisung ausgeführt. Wennbreak
auftritt, verlässt das Programm dieswitch
und setzt die Ausführung bei der Anweisung nachswitch
fort. Wennbreak
weggelassen würde, würde auch die Anweisung fürcase "Cherries"
ausgeführt.
switch (fruitType) { case "Oranges": console.log("Oranges are $0.59 a pound."); break; case "Apples": console.log("Apples are $0.32 a pound."); break; case "Bananas": console.log("Bananas are $0.48 a pound."); break; case "Cherries": console.log("Cherries are $3.00 a pound."); break; case "Mangoes": console.log("Mangoes are $0.56 a pound."); break; case "Papayas": console.log("Papayas are $2.79 a pound."); break; default: console.log(`Sorry, we are out of ${fruitType}.`);}console.log("Is there anything else you'd like?");
Anweisungen zur Ausnahmebehandlung
Sie können Ausnahmen mit derthrow
-Anweisung werfen und diese mit dentry...catch
-Anweisungen behandeln.
Typen von Ausnahmen
In JavaScript kann nahezu jedes Objekt geworfen werden. Dennoch sind nicht alle geworfenen Objekte gleich. Während es üblich ist, Zahlen oder Strings als Fehler zu werfen, ist es oft effektiver, einen der speziell für diesen Zweck entwickelten Ausnahmetypen zu verwenden:
throw-Anweisung
Verwenden Sie diethrow
-Anweisung, um eine Ausnahme zu werfen. Einethrow
-Anweisung gibt den zu werfenden Wert an:
throw expression;
Sie können jeden Ausdruck werfen, nicht nur Ausdrücke eines bestimmten Typs. Der folgende Code wirft mehrere Ausnahmen unterschiedlicher Typen:
throw "Error2"; // String typethrow 42; // Number typethrow true; // Boolean typethrow { toString() { return "I'm an object!"; },};
try...catch-Anweisung
Dietry...catch
-Anweisung kennzeichnet einen Anweisungsblock, der versucht wird, und gibt eine oder mehrere Antworten an, falls eine Ausnahme geworfen wird. Wenn eine Ausnahme geworfen wird, fängt dietry...catch
-Anweisung diese ab.
Dietry...catch
-Anweisung besteht aus einemtry
-Block, der eine oder mehrere Anweisungen enthält, und einemcatch
-Block, der Anweisungen enthält, die angeben, was zu tun ist, falls eine Ausnahme imtry
-Block geworfen wird.
Mit anderen Worten, Sie möchten, dass dertry
-Block erfolgreich ist—aber wenn er das nicht ist, möchten Sie, dass die Kontrolle an dencatch
-Block übergeben wird. Wenn eine Anweisung innerhalb destry
-Blocks (oder in einer Funktion, die innerhalb destry
-Blocks aufgerufen wird) eine Ausnahme wirft, verschiebt sich die Kontrollesofort auf dencatch
-Block. Wenn keine Ausnahme imtry
-Block geworfen wird, wird dercatch
-Block übersprungen. Derfinally
-Block wird nach Ausführung dertry
- undcatch
-Blöcke, aber vor den Anweisungen nach dertry...catch
-Anweisung ausgeführt.
Das folgende Beispiel verwendet einetry...catch
-Anweisung. Das Beispiel ruft eine Funktion auf, die einen Monatsnamen aus einem Array basierend auf dem an die Funktion übergebenen Wert abruft. Wenn der Wert keiner Monatszahl (1
–12
) entspricht, wird eine Ausnahme mit dem Wert'InvalidMonthNo'
geworfen und die Anweisungen imcatch
-Block setzen die VariablemonthName
auf'unknown'
.
function getMonthName(mo) { mo--; // Adjust month number for array index (so that 0 = Jan, 11 = Dec) // prettier-ignore const months = [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", ]; if (!months[mo]) { throw new Error("Invalid month code"); // throw keyword is used here } return months[mo];}try { // statements to try monthName = getMonthName(myMonth); // function could throw exception} catch (e) { monthName = "unknown"; logMyErrors(e); // pass exception object to error handler (i.e. your own function)}
Der catch-Block
Sie können einencatch
-Block verwenden, um alle Ausnahmen zu behandeln, die imtry
-Block generiert werden können.
catch (exception) { statements}
Dercatch
-Block spezifiziert einen Bezeichner (exception
im vorherigen Syntaxbeispiel), der den Wert enthält, der durch diethrow
-Anweisung angegeben wird. Sie können diesen Bezeichner verwenden, um Informationen über die geworfene Ausnahme zu erhalten.
JavaScript erstellt diesen Bezeichner, wenn dercatch
-Block betreten wird. Der Bezeichner existiert nur für die Dauer descatch
-Blocks. Sobald dercatch
-Block die Ausführung abgeschlossen hat, existiert der Bezeichner nicht mehr.
Zum Beispiel wirft der folgende Code eine Ausnahme. Wenn die Ausnahme auftritt, wird die Kontrolle auf dencatch
-Block übertragen.
try { throw "myException"; // generates an exception} catch (err) { // statements to handle any exceptions logMyErrors(err); // pass exception object to error handler}
Hinweis:Beim Protokollieren von Fehlern in der Konsole innerhalb einescatch
-Blocks wird empfohlen,console.error()
anstattconsole.log()
zu verwenden, um zu debuggen. Es formatiert die Nachricht als Fehler und fügt sie zur Liste der von der Seite generierten Fehlermeldungen hinzu.
Der finally-Block
Derfinally
-Block enthält Anweisungen, dienach der Ausführung dertry
- undcatch
-Blöcke ausgeführt werden. Darüber hinaus wird derfinally
-Blockvor dem Code ausgeführt, der auf dietry…catch…finally
-Anweisung folgt.
Es ist auch wichtig zu beachten, dass derfinally
-Block ausgeführt wird,unabhängig davon, ob eine Ausnahme geworfen wird oder nicht. Wenn jedoch eine Ausnahme geworfen wird, werden die Anweisungen imfinally
-Block selbst dann ausgeführt, wenn keincatch
-Block die geworfene Ausnahme behandelt.
Sie können denfinally
-Block verwenden, um Ihr Skript bei Auftreten einer Ausnahme elegant fehlschlagen zu lassen. Zum Beispiel müssen Sie möglicherweise eine Ressource freigeben, die Ihr Skript belegt hat.
Das folgende Beispiel öffnet eine Datei und führt dann Anweisungen aus, die die Datei nutzen. (Serverseitiges JavaScript ermöglicht den Zugriff auf Dateien.) Wenn während des geöffneten Zustands der Datei eine Ausnahme geworfen wird, schließt derfinally
-Block die Datei, bevor das Skript fehlschlägt. Die Verwendung vonfinally
hiergewährleistet, dass die Datei nie offen bleibt, selbst wenn ein Fehler auftritt.
openMyFile();try { writeMyFile(theData); // This may throw an error} catch (e) { handleError(e); // If an error occurred, handle it} finally { closeMyFile(); // Always close the resource}
Wenn derfinally
-Block einen Wert zurückgibt, wird dieser Wert zum Rückgabewert der gesamtentry…catch…finally
-Produktion, unabhängig von jeglichenreturn
-Anweisungen in dentry
- undcatch
-Blöcken:
function f() { try { console.log(0); throw "bogus"; } catch (e) { console.log(1); // This return statement is suspended // until finally block has completed return true; console.log(2); // not reachable } finally { console.log(3); return false; // overwrites the previous "return" console.log(4); // not reachable } // "return false" is executed now console.log(5); // not reachable}console.log(f()); // 0, 1, 3, false
Das Überschreiben von Rückgabewerten durch denfinally
-Block gilt auch für Ausnahmen, die innerhalb descatch
-Blocks geworfen oder erneut geworfen werden:
function f() { try { throw "bogus"; } catch (e) { console.log('caught inner "bogus"'); // This throw statement is suspended until // finally block has completed throw e; } finally { return false; // overwrites the previous "throw" } // "return false" is executed now}try { console.log(f());} catch (e) { // this is never reached! // while f() executes, the `finally` block returns false, // which overwrites the `throw` inside the above `catch` console.log('caught outer "bogus"');}// Logs:// caught inner "bogus"// false
Verschachteln von try...catch-Anweisungen
Sie können eine oder mehreretry...catch
-Anweisungen verschachteln.
Wenn ein innerertry
-Blocknicht über einen entsprechendencatch
-Block verfügt:
- muss ereinen
finally
-Block enthalten, und - wird der
catch
-Block der umschließendentry...catch
-Anweisung auf ein passendes Element überprüft.
Weitere Informationen finden Sie unterverschachtelte try-Blöcke auf dertry...catch
-Referenzseite.
Nutzung von Error-Objekten
Abhängig vom Fehlertyp können Sie die Eigenschaftenname
undmessage
verwenden, um eine genauere Nachricht zu erhalten.
Die Eigenschaftname
liefert die allgemeine Klasse desError
(wieDOMException
oderError
), währendmessage
im Allgemeinen eine prägnantere Nachricht liefert, als man durch die Umwandlung des Fehlerobjekts in einen String erhalten würde.
Wenn Sie Ihre eigenen Ausnahmen werfen, um diese Eigenschaften nutzen zu können (wie zum Beispiel, wenn Ihrcatch
-Block nicht zwischen Ihren eigenen Ausnahmen und Systemausnahmen differenziert), können Sie denError
-Konstruktor verwenden.
Zum Beispiel:
function doSomethingErrorProne() { if (ourCodeMakesAMistake()) { throw new Error("The message"); } doSomethingToGetAJavaScriptError();}try { doSomethingErrorProne();} catch (e) { // Now, we actually use `console.error()` console.error(e.name); // 'Error' console.error(e.message); // 'The message', or a JavaScript error message}
MDN-Feedback-Box
Diese Seite wurde automatisch aus dem Englischen übersetzt.