Die Themen in diesem Teil der Übersetzung des JavaScript-Lernprogramms sind Ausnahmebehandlung, automatische Semikolonfunktionen und Vorlagenliterale.
→
Teil 1: Erstes Programm, Sprachfunktionen, Standards→
Teil 2: Codestil und Programmstruktur→
Teil 3: Variablen, Datentypen, Ausdrücke, Objekte→
Teil 4: Funktionen→
Teil 5: Arrays und Loops→
Teil 6: Ausnahmen, Semikolons, Platzhalterliterale→
Teil 7: Strict Mode, dieses Schlüsselwort, Ereignisse, Module, mathematische Berechnungen→
Teil 8: Übersicht über die ES6-Funktionen→
Teil 9: Übersicht über die ES7-, ES8- und ES9-Standards
Ausnahmebehandlung
Wenn während der Codeausführung ein Problem auftritt, wird es in JavaScript als Ausnahme ausgedrückt. Wenn Sie keine Maßnahmen zur Behandlung von Ausnahmen ergreifen, wird die Programmausführung bei Auftreten gestoppt und eine Fehlermeldung in der Konsole angezeigt.
Betrachten Sie das folgende Code-Snippet.
let obj = {value: 'message text'} let notObj let fn = (a) => a.value console.log(fn(obj))
Hier haben wir eine Funktion, mit der wir Objekte mit der Eigenschaft
value
möchten. Sie gibt diese Eigenschaft zurück. Wenn Sie diese Funktion für den beabsichtigten Zweck verwenden, dh um ein Objekt zu übertragen, mit dem sie arbeiten soll, werden bei der Ausführung keine Fehler generiert. Wenn Sie jedoch etwas Unangemessenes übergeben, in unserem Fall eine deklarierte, aber nicht initialisierte Variable, tritt ein Fehler auf, wenn Sie versuchen, auf die
value
Eigenschaft eines
undefined
Werts zuzugreifen. In der Konsole wird eine Fehlermeldung angezeigt, die Programmausführung wird gestoppt.
So sieht es aus, wenn Sie diesen Code in Node.js ausführen.
TypeError-Ausnahme in Node.js.Wenn im JS-Code einer Webseite so etwas vorkommt, wird eine ähnliche Nachricht an die Browserkonsole gesendet. Wenn dies beispielsweise in einem realen Programm geschieht, ist dieses Verhalten im Webserver-Code äußerst unerwünscht. Es wäre schön, einen Mechanismus zu haben, der es ermöglicht, ohne das Programm zu stoppen, den Fehler abzufangen und dann Maßnahmen zu ergreifen, um ihn zu korrigieren. Ein solcher Mechanismus existiert in JavaScript und wird durch das Konstrukt
try...catch
.
Konstruktionsversuch ... fangen
Mit dem Konstrukt
try...catch
können Sie Ausnahmen abfangen und behandeln. Es enthält nämlich einen
try
Block, der Code enthält, der einen Fehler verursachen kann, und einen
catch
, in dem die Steuerung übertragen wird, wenn ein Fehler auftritt.
try
Blöcke enthalten nicht den gesamten Programmcode. Dort werden die Teile platziert, die Laufzeitfehler verursachen können. Zum Beispiel Aufrufe von Funktionen, die mit bestimmten Daten arbeiten müssen, die von externen Quellen empfangen wurden. Wenn sich die Struktur solcher Daten von den Erwartungen der Funktion unterscheidet, kann ein Fehler auftreten. So sieht das Designdiagramm
try...catch
aus.
try {
Wenn der Code fehlerfrei ausgeführt wird, wird der
catch
(Exception-Handler) nicht ausgeführt. Wenn ein Fehler auftritt, wird das Fehlerobjekt dorthin übertragen und es werden einige Maßnahmen ergriffen, um diesen Fehler zu bekämpfen.
Wir wenden diese Konstruktion in unserem Beispiel an und schützen mit ihrer Hilfe gefährliche Abschnitte des Programms - diejenigen, in denen die Funktion
fn()
aufgerufen wird.
let obj = {value: 'message text'} let notObj let fn = (a) => a.value try { console.log(fn(obj)) } catch (e) { console.log(e.message) } console.log('Before')
Schauen wir uns die Ergebnisse der Ausführung dieses Codes in Node.js an.
Fehlerbehandlung in Node.js.Wenn Sie dieses Beispiel mit dem vorherigen vergleichen, wird, wie Sie sehen, der gesamte Code ausgeführt, und der Code, der sich vor der Problemzeile befindet, und der Code, der sich danach befindet. Wir "verarbeiten" den Fehler, indem wir einfach die Werte der
message
des
Fehlerobjekts auf die Konsole drucken. Wie mit dem Fehler umgegangen wird, der im tatsächlich verwendeten Code aufgetreten ist, hängt vom Fehler ab.
Wir haben den
try...catch
Block oben besprochen, aber tatsächlich enthält dieses Konstrukt einen weiteren Block -
finally
.
▍ endlich blockieren
Der
finally
Block enthält Code, der ausgeführt wird, unabhängig davon, ob im Code, der im
try
Block ausgeführt wird, ein Fehler aufgetreten ist. So sieht es aus.
try {
Der
finally
Block kann auch verwendet werden, wenn der
try...catch...finally
Block keinen
catch
. Bei diesem Ansatz wird es auf die gleiche Weise wie bei der Konstruktion mit dem
catch
, um beispielsweise die im
try
Block belegten Ressourcen freizugeben.
▍ Verschachtelte Versuchsblöcke
Versuchsblöcke können zusammen verschachtelt werden. In diesem Fall wird die Ausnahme im nächsten
catch
.
try {
In diesem Fall wird eine Ausnahme, die im internen
try
Block auftritt, im externen
catch
.
▍ Selbst generierte Ausnahme
Ausnahmen können Sie selbst mit der
throw
Anweisung
throw
. So sieht es aus.
throw value
Nachdem dieser Befehl ausgeführt wurde, wird die Steuerung an den nächsten
catch
, oder wenn ein solcher Block nicht gefunden werden kann, stoppt das Programm. Der Ausnahmewert kann beliebig sein. Zum Beispiel ein benutzerdefiniertes Fehlerobjekt.
Über Semikolons
Die Verwendung von Semikolons in JavaScript ist optional. Einige Programmierer verzichten auf sie, verlassen sich auf ein automatisches Anordnungssystem und platzieren sie nur dort, wo es unbedingt erforderlich ist. Manche Leute ziehen es vor, sie wo immer möglich zu platzieren. Der Autor dieses Materials bezieht sich auf die Kategorie der Programmierer, die auf Semikolons verzichten möchten. Er sagte, er habe beschlossen, im Herbst 2017 auf sie zu verzichten, indem er Prettier so eingestellt habe, dass sie gelöscht werden, wo immer Sie ohne ihre explizite Einfügung auskommen können. Code ohne Semikolons sieht seiner Meinung nach natürlicher und leichter zu lesen aus.
Vielleicht können wir sagen, dass die Community der JS-Entwickler in Bezug auf Semikolons in zwei Lager unterteilt ist. Gleichzeitig gibt es auch JavaScript-Styleguides, die explizite Semikolons vorschreiben, und Guides, die empfehlen, auf diese zu verzichten.
All dies ist möglich, weil JavaScript über ein System für automatische Semikolons (Automatic Semicolon Insertion, ASI) verfügt. Die Tatsache, dass Sie in JS-Code in vielen Situationen auf diese Zeichen verzichten können, und die Tatsache, dass die Semikolons automatisch platziert werden, wenn der Code für die Ausführung vorbereitet wird, bedeutet jedoch nicht, dass der Programmierer die Regeln, nach denen dies geschieht, nicht kennen muss. Das Ignorieren dieser Regeln führt zu Fehlern.
▍ Regeln für automatische Semikolons
Der JavaScript-Parser fügt beim Parsen von Programmtext in den folgenden Situationen automatisch Semikolons hinzu:
- Wenn die nächste Zeile mit einem Code beginnt, der den aktuellen Code unterbricht (der Code eines bestimmten Befehls kann sich in mehreren Zeilen befinden).
- Wenn die nächste Zeile mit dem Zeichen
}
beginnt, wird der aktuelle Block geschlossen. - Wenn das Ende der Datei mit dem Programmcode erkannt wird.
- In der Zeile mit dem
return
. - In der Zeile mit dem Befehl
break
. - In der Zeile mit dem
throw
. - In der Zeile mit dem Befehl
continue
.
▍ Beispiele für Code, der nicht wie erwartet funktioniert
Hier sind einige Beispiele, die die obigen Regeln veranschaulichen. Was wird Ihrer Meinung nach beispielsweise als Ergebnis der Ausführung des folgenden Codefragments angezeigt?
const hey = 'hey' const you = 'hey' const heyYou = hey + ' ' + you ['h', 'e', 'y'].forEach((letter) => console.log(letter))
Beim Versuch, diesen Code auszuführen, wird ein nicht
Uncaught TypeError: Cannot read property 'forEach' of undefined
Fehler
Uncaught TypeError: Cannot read property 'forEach' of undefined
Systems
Uncaught TypeError: Cannot read property 'forEach' of undefined
werden, basierend auf Regel Nr. 1. Es wird versucht, den Code wie folgt zu interpretieren.
const hey = 'hey'; const you = 'hey'; const heyYou = hey + ' ' + you['h', 'e', 'y'].forEach((letter) => console.log(letter))
Das Problem kann gelöst werden, indem nach der vorletzten Zeile des ersten Beispiels ein Semikolon eingefügt wird.
Hier ist ein weiterer Code.
(1 + 2).toString()
Das Ergebnis seiner Ausführung ist die Ausgabe der Zeichenfolge
"3"
. Aber was passiert, wenn so etwas im nächsten Code-Snippet erscheint?
const a = 1 const b = 2 const c = a + b (a + b).toString()
In dieser Situation wird ein
TypeError: b is not a function
Fehler
TypeError: b is not a function
da der obige Code wie folgt interpretiert wird.
const a = 1 const b = 2 const c = a + b(a + b).toString()
Schauen wir uns nun ein Beispiel an, das auf Regel 4 basiert.
(() => { return { color: 'white' } })()
Sie könnten denken, dass dieses IIFE ein Objekt zurückgibt, das die
color
, aber tatsächlich ist dies nicht der Fall. Stattdessen gibt die Funktion
undefined
da das System nach dem Befehl
return
ein Semikolon hinzufügt.
Um ein ähnliches Problem zu lösen, muss die öffnende Klammer des Objektliteral in derselben Zeile wie der
return
.
(() => { return { color: 'white' } })()
Wenn Sie sich das folgende Codefragment ansehen, denken Sie möglicherweise, dass im Meldungsfeld
0
angezeigt wird.
1 + 1 -1 + 1 === 0 ? alert(0) : alert(2)
Es wird jedoch 2 ausgegeben, da dieser Code gemäß Regel Nr. 1 wie folgt dargestellt wird.
1 + 1 -1 + 1 === 0 ? alert(0) : alert(2)
Sie sollten vorsichtig sein, wenn Sie Semikolons in JavaScript verwenden. Sie können sowohl begeisterte Anhänger von Semikolons als auch deren Gegner treffen. Wenn Sie entscheiden, ob Semikolons in Ihrem Code benötigt werden, können Sie sich darauf verlassen, dass JS die automatische Ersetzung unterstützt. Jeder muss jedoch selbst entscheiden, ob sie in seinem Code benötigt werden oder nicht. Die Hauptsache ist, den gewählten Ansatz konsequent und vernünftig anzuwenden. In Bezug auf die Platzierung von Semikolons und die Struktur des Codes können wir die folgenden Regeln empfehlen:
- Ordnen Sie mit dem Befehl return in derselben Zeile wie der Befehl an, was von der Funktion zurückgegeben werden soll. Das gleiche gilt für die Befehle
break
, throw
, continue
. - Achten Sie besonders auf Situationen, in denen eine neue Codezeile mit einer Klammer beginnt, da diese Zeile automatisch mit der vorherigen kombiniert und vom System als Versuch dargestellt werden kann, eine Funktion aufzurufen oder auf ein Array-Element zuzugreifen.
Im Allgemeinen kann gesagt werden, dass Sie den Code testen müssen, um sicherzustellen, dass er genau wie erwartet funktioniert, unabhängig davon, ob Sie selbst Semikolons einfügen oder sich auf deren automatische Platzierung verlassen.
Anführungszeichen und Platzhalterliterale
Lassen Sie uns über die Funktionen der Verwendung von Anführungszeichen in JavaScript sprechen. Wir sprechen nämlich über die folgenden Arten von Anführungszeichen, die in JS-Programmen zulässig sind:
- Einfache Anführungszeichen.
- Doppelte Anführungszeichen.
- Zurück Zitate.
Einfache und doppelte Anführungszeichen können im Allgemeinen als gleich angesehen werden.
const test = 'test' const bike = "bike"
Es gibt praktisch keinen Unterschied zwischen ihnen. Möglicherweise besteht der einzige merkliche Unterschied darin, dass Sie in Zeichenfolgen in einfachen Anführungszeichen das Zeichen eines einfachen Anführungszeichens umgehen müssen und in Zeichenfolgen in doppelten Anführungszeichen das Zeichen doppelt ist.
const test = 'test' const test = 'te\'st' const test = 'te"st' const test = "te\"st" const test = "te'st"
In verschiedenen Styleguides finden Sie sowohl eine Empfehlung für die Verwendung von einfachen Anführungszeichen als auch eine Empfehlung für die Verwendung von doppelten Anführungszeichen. Der Autor dieses Materials sagt, dass er im JS-Code ausschließlich einfache Anführungszeichen verwendet und doppelte Anführungszeichen nur im HTML-Code verwendet.
Backticks wurden mit der Veröffentlichung des ES6-Standards im Jahr 2015 in JavaScript veröffentlicht. Sie ermöglichen unter anderem die bequeme Beschreibung von mehrzeiligen Zeichenfolgen. Solche Zeichenfolgen können auch mit regulären Anführungszeichen angegeben werden - mithilfe der Escape-Sequenz
\n
. Es sieht so aus.
const multilineString = 'A string\non multiple lines'
Anführungszeichen (normalerweise befindet sich die Schaltfläche zur Eingabe links von der Zifferntaste 1 auf der Tastatur) verzichten auf
\n
.
const multilineString = `A string on multiple lines`
Die Möglichkeiten von Backquotes sind jedoch nicht darauf beschränkt. Wenn also eine Zeichenfolge mit Anführungszeichen beschrieben wird, können Werte aus der Berechnung von JS-Ausdrücken mithilfe der Konstruktion
${}
.
const multilineString = `A string on ${1+1} lines`
Solche Zeichenfolgen werden Vorlagenliterale genannt.
Vorlagenliterale weisen die folgenden Funktionen auf:
- Sie unterstützen mehrzeiligen Text.
- Sie ermöglichen die Interpolation von Zeichenfolgen, in die integrierte Ausdrücke verwendet werden können.
- Mit ihnen können Sie mit getaggten Vorlagen arbeiten und so Ihre eigenen domänenspezifischen Sprachen (DSL, domänenspezifische Sprache) erstellen.
Lassen Sie uns über diese Funktionen sprechen.
▍Multilinischer Text
Wenn Sie mehrzeilige Texte mit Anführungszeichen setzen, müssen Sie berücksichtigen, dass Leerzeichen in solchen Texten genauso wichtig sind wie andere Zeichen. Betrachten Sie beispielsweise den folgenden mehrzeiligen Text.
const string = `First Second`
Seine Schlussfolgerung wird ungefähr Folgendes ergeben.
First Second
Das heißt, es stellt sich heraus, dass der Programmierer bei der Eingabe dieses Textes im Editor möglicherweise erwartet hat, dass die Wörter
First
und
Second
bei der Ausgabe streng untereinander erscheinen, aber tatsächlich ist dies nicht der Fall. Um dieses Problem zu umgehen, können Sie mehrzeiligen Text mit einem Zeilenvorschub starten und unmittelbar nach dem Schließen des hinteren Anführungszeichens die Methode
trim()
aufrufen, mit der Leerzeichen am Anfang oder Ende der Zeile entfernt werden. Zu diesen Zeichen gehören insbesondere Leerzeichen und Tabulatoren. Die Zeilenendezeichen werden ebenfalls gelöscht.
Es sieht so aus.
const string = ` First Second`.trim()
▍ Interpolation
Mit Interpolation meinen wir hier die Umwandlung von Variablen und Ausdrücken in Strings. Dies erfolgt mit dem Konstrukt
${}
.
const variable = 'test' const string = `something ${ variable }`
Sie können dem
${}
-Block alles hinzufügen - sogar Ausdrücke.
const string = `something ${1 + 2 + 3}` const string2 = `something ${foo() ? 'x' : 'y' }`
Der Text
something 6
wird in die
string
, entweder der Text
something x
oder der Text
something y
wird in die Konstante
string2
. Es hängt davon ab, ob die Funktion
foo()
true oder false zurückgibt (hier wird der ternäre Operator verwendet, der, wenn das, was vor dem Fragezeichen steht, wahr ist, das zurückgibt, was nach dem Fragezeichen kommt, andernfalls was zurückgibt kommt nach dem Doppelpunkt).
▍Tagged Templates
Mit Tags versehene Vorlagen werden in vielen gängigen Bibliotheken verwendet. Unter ihnen sind
Styled Components ,
Apollo ,
GraphQL .
Welche solchen Muster ausgegeben werden, unterliegt einer durch die Funktion definierten Logik. Hier ist ein leicht überarbeitetes Beispiel in einer unserer
Veröffentlichungen, das zeigt, wie mit markierten Vorlagenzeichenfolgen gearbeitet wird.
const esth = 8 function helper(strs, ...keys) { const str1 = strs[0]
Wenn hier die Zahl
8
in die
esth
Konstante geschrieben ist, wird die Zeile
ES 8 is awesome
sein. Andernfalls wird es eine andere Zeile geben. Wenn
esth
beispielsweise
esth
Nummer
6
esth
,
esth
es so aus, als wäre
ES 6 is good
.
Styled Components verwendet markierte Vorlagen, um CSS-Zeichenfolgen zu definieren.
const Button = styled.button` font-size: 1.5em; background-color: black; color: white; `;
Bei Apollo werden sie zum Definieren von GraphQL-Abfragen verwendet.
const query = gql` query { ... } `
Wenn Sie wissen, wie getaggte Vorlagen funktionieren, ist es leicht zu verstehen, dass
styled.button
und
gql
aus den vorherigen Beispielen nur Funktionen sind.
function gql(literals, ...expressions) { }
Beispielsweise gibt die Funktion
gql()
eine Zeichenfolge zurück, die das Ergebnis einer Berechnung sein kann. Der
literals
Parameter dieser Funktion ist ein Array, das den Inhalt eines Vorlagenliterals enthält, das in Teile unterteilt ist.
expresions
enthalten die Ergebnisse der Auswertung von Ausdrücken.
Lassen Sie uns die nächste Zeile analysieren.
const string = helper`something ${1 + 2 + 3} `
Die
helper
ruft das
literals
Array ab, das zwei Elemente enthält. Im ersten wird ein Text mit einem Leerzeichen dahinter stehen, im zweiten wird eine leere Zeile angezeigt, dh zwischen dem Ausdruck
${1 + 2 + 3}
und dem Ende der Zeile. Es wird ein Element im
espressions
Array geben -
6
.
Hier ist ein komplexeres Beispiel.
const string = helper`something another ${'x'} new line ${1 + 2 + 3} test`
Hier wird in der
helper
das nächste Array als erster Parameter abgerufen.
[ 'something\nanother ', '\nnew line ', '\ntest' ]
Das zweite Array sieht folgendermaßen aus.
[ 'x', 6 ]
Zusammenfassung
Heute haben wir über die Ausnahmebehandlung, über die automatische Substitution von Semikolons und über Vorlagenliterale in JavaScript gesprochen. Das nächste Mal werden wir uns einige wichtigere Konzepte der Sprache ansehen. Insbesondere - Arbeiten im strengen Modus, Timer, mathematische Berechnungen.
Liebe Leser! Verwenden Sie die Funktionen von getaggten Vorlagen in JavaScript?
