Was ist schiefgelaufen? JavaScript-Fehlerbehebung
Als Sie das "Errate die Zahl"-Spiel im vorherigen Artikel aufgebaut haben, haben Sie vielleicht festgestellt, dass es nicht funktionierte. Keine Sorge — dieser Artikel soll Ihnen davor bewahren, bei solchen Problemen verzweifelt zu werden, indem er Ihnen einige Tipps gibt, wie Sie Fehler in JavaScript-Programmen finden und beheben können.
Voraussetzungen: | Ein Verständnis von HTML und den Grundlagen von CSS, grundlegende Erfahrung im Schreiben von JavaScript. |
---|---|
Lernergebnisse: |
|
Fehlerarten
Im Allgemeinen gibt es zwei Haupttypen von Fehlern, auf die Sie stoßen, wenn Sie im Code etwas falsch machen:
- Syntaxfehler: Dies sind Rechtschreibfehler in Ihrem Code, die tatsächlich dazu führen, dass das Programm gar nicht läuft oder mittendrin aufhört zu funktionieren — in der Regel werden Ihnen auch Fehlermeldungen angezeigt. Diese sind normalerweise nicht allzu schwer zu beheben, solange Sie mit den richtigen Werkzeugen vertraut sind und wissen, was die Fehlermeldungen bedeuten!
- Logikfehler: Dies sind Fehler, bei denen die Syntax zwar korrekt ist, der Code jedoch nicht das tut, was Sie beabsichtigt haben. Das bedeutet, dass das Programm erfolgreich ausgeführt wird, aber falsche Ergebnisse liefert. Diese sind oft schwieriger zu beheben als Syntaxfehler, da es in der Regel keine Fehlermeldung gibt, die Sie auf die Fehlerquelle hinweist.
Okay, so einfach ist es dann doch nicht — es gibt noch einige andere Unterscheidungen, wenn Sie tiefer einsteigen. Aber die obigen Klassifikationen reichen in dieser frühen Phase Ihrer Karriere aus. Wir werden uns im Folgenden mit beiden Fehlerarten befassen.
Ein fehlerhaftes Beispiel
Um zu beginnen, kehren wir zu unserem Zahlerratenspiel zurück — nur dass wir diesmal eine Version untersuchen, die einige absichtlich eingeführte Fehler enthält. Gehen Sie zu GitHub und erstellen Sie sich eine lokale Kopie von number-game-errors.html (sehen Sie sich das live hier an).
- Öffnen Sie zu Beginn die lokale Kopie in Ihrem bevorzugten Texteditor und in Ihrem Browser.
- Versuchen Sie, das Spiel zu spielen — Sie werden feststellen, dass es nicht funktioniert, wenn Sie die Schaltfläche "Versuch abschicken" drücken!
Hinweis: Möglicherweise haben Sie auch Ihre eigene Version des Spielbeispiels, das nicht funktioniert und das Sie reparieren möchten! Wir möchten dennoch, dass Sie den Artikel mit unserer Version durcharbeiten, damit Sie die hier vermittelten Techniken lernen. Dann können Sie zurückgehen und versuchen, Ihr Beispiel zu reparieren.
An diesem Punkt werfen wir einen Blick in die Entwicklerkonsole, um zu sehen, ob sie Syntaxfehler meldet, und versuchen dann, diese zu beheben. Sie lernen weiter unten, wie das geht.
Behebung von Syntaxfehlern
Früher im Kurs haben wir Sie dazu gebracht, einige einfache JavaScript-Befehle in die JavaScript-Konsole der Entwicklerwerkzeuge einzugeben (wenn Sie sich nicht erinnern können, wie Sie diese in Ihrem Browser öffnen, folgen Sie dem vorangehenden Link, um herauszufinden, wie). Was noch nützlicher ist, ist, dass Ihnen die Konsole Fehlermeldungen anzeigt, wann immer ein Syntaxfehler im JavaScript besteht, das in die JavaScript-Engine des Browsers eingegeben wird. Jetzt gehen wir auf die Suche.
-
Gehen Sie zu dem Tab, in dem Sie
number-game-errors.html
geöffnet haben, und öffnen Sie Ihre JavaScript-Konsole. Sie sollten eine Fehlermeldung in etwa folgender Form sehen: -
Die erste Zeile der Fehlermeldung lautet:
Uncaught TypeError: guessSubmit.addeventListener is not a function number-game-errors.html:87:19
- Der erste Teil,
Uncaught TypeError: guessSubmit.addeventListener is not a function
, sagt uns etwas darüber, was schiefgelaufen ist. - Der zweite Teil,
number-game-errors.html:87:19
, sagt uns, wo im Code der Fehler aufgetreten ist: Zeile 87, Zeichen 19 der Datei "number-game-errors.html".
- Der erste Teil,
-
Wenn wir uns Zeile 87 in unserem Code-Editor ansehen, finden wir diese Zeile:
jsguessSubmit.addeventListener("click", checkGuess);
-
Die Fehlermeldung lautet: "guessSubmit.addeventListener is not a function", was bedeutet, dass die Funktion, die wir aufrufen, vom JavaScript-Interpreter nicht erkannt wird. Oft bedeutet diese Fehlermeldung tatsächlich, dass wir etwas falsch geschrieben haben. Wenn Sie sich nicht sicher sind, wie die richtige Schreibweise eines Syntaxelements lautet, ist es oft gut, nach der Funktion auf MDN zu suchen. Der beste Weg, dies derzeit zu tun, besteht darin, mit Ihrer bevorzugten Suchmaschine nach "mdn name-of-feature" zu suchen. Hier ist eine Abkürzung, um Ihnen in diesem Fall etwas Zeit zu sparen:
addEventListener()
. -
Wenn wir die Seite betrachten, scheint der Fehler darin zu bestehen, dass wir den Funktionsnamen falsch geschrieben haben! Denken Sie daran, dass JavaScript zwischen Groß- und Kleinschreibung unterscheidet, daher führt jeder kleine Unterschied in der Schreibweise oder Groß-/Kleinschreibung zu einem Fehler. Das Ändern von
addeventListener
zuaddEventListener
sollte dies beheben. Machen Sie das jetzt.
Hinweis: Weitere Einzelheiten zu diesem Fehler finden Sie auf unserer Referenzseite TypeError: "x" is not a function.
Syntaxfehler Runde zwei
-
Speichern Sie Ihre Seite und aktualisieren Sie sie, und Sie sollten sehen, dass der Fehler verschwunden ist.
-
Wenn Sie jetzt versuchen, einen Tipp einzugeben und die Schaltfläche "Versuch abschicken" zu drücken, sehen Sie einen weiteren Fehler!
-
Diesmal lautet der gemeldete Fehler:
Uncaught TypeError: can't access property "textContent", lowOrHi is null
Abhängig vom verwendeten Browser können Sie hier eine andere Meldung sehen. Die obige Meldung ist das, was Ihnen Firefox zeigt, aber Chrome zeigt Ihnen zum Beispiel Folgendes:
Uncaught TypeError: Cannot set properties of null (setting 'textContent')
Es ist derselbe Fehler, aber unterschiedliche Browser beschreiben ihn auf unterschiedliche Weise.
Hinweis: Dieser Fehler trat nicht sofort auf, als die Seite geladen wurde, weil dieser Fehler innerhalb einer Funktion (innerhalb des Blockes
checkGuess() { }
) auftrat. Wie Sie in unserem späteren Funktionen-Artikel ausführlicher lernen werden, wird Code innerhalb von Funktionen in einem separaten Bereich als Code außerhalb von Funktionen ausgeführt. In diesem Fall wurde der Code nicht ausgeführt und der Fehler wurde nicht ausgelöst, bis die FunktioncheckGuess()
durch Zeile 87 ausgeführt wurde. -
Die in der Fehlermeldung angegebene Zeilennummer ist 79. Werfen Sie einen Blick auf Zeile 79, und Sie werden den folgenden Code sehen:
jslowOrHi.textContent = "Last guess was too high!";
-
Diese Zeile versucht, die Eigenschaft
textContent
der VariablenlowOrHi
auf eine Textzeichenkette zu setzen, aber es funktioniert nicht, weillowOrHi
nicht das enthält, was es soll. Sehen wir uns an, warum das so ist — versuchen Sie, nach anderen Instanzen vonlowOrHi
im Code zu suchen. Die früheste Instanz, die Sie finden, ist in Zeile 51:jsconst lowOrHi = document.querySelector("lowOrHi");
-
An diesem Punkt versuchen wir, die Variable mit einem Verweis auf ein Element im HTML-Dokument zu füllen. Lassen Sie uns sehen, was die Variable nach dem Ausführen dieser Zeile enthält. Fügen Sie folgenden Code in Zeile 54 hinzu:
jsconsole.log(lowOrHi);
Dieser Code druckt den Wert von
lowOrHi
in der Konsole aus, nachdem wir versucht haben, ihn in Zeile 51 zu setzen. Weitere Informationen finden Sie unterconsole.log()
. -
Speichern und aktualisieren Sie die Seite, und Sie sollten nun das
console.log()
-Ergebnis in Ihrer Konsole sehen. Sicher genug, der Wert vonlowOrHi
ist an diesem Punktnull
, und das stimmt mit der Firefox-FehlermeldunglowOrHi is null
überein. Es gibt also definitiv ein Problem mit Zeile 51. Der Wertnull
bedeutet "nichts" oder "kein Wert". Unser Code, umlowOrHi
auf ein Element zu setzen, funktioniert also nicht. -
Lassen Sie uns überlegen, was das Problem sein könnte. Zeile 51 verwendet eine Methode
document.querySelector()
, um einen Verweis auf ein Element zu erhalten, indem es mit einem CSS-Selektor ausgewählt wird. Schauen wir weiter oben in unserer Datei nach, wir können den betreffenden Absatz finden:html<p class="lowOrHi"></p>
-
Wir brauchen also einen Klassenselektor hier, der mit einem Punkt (
.
) beginnt, aber der Selektor, der in der MethodequerySelector()
in Zeile 51 übergeben wird, hat keinen Punkt. Das könnte das Problem sein! Versuchen Sie,lowOrHi
in Zeile 51 in.lowOrHi
zu ändern. -
Speichern und aktualisieren Sie die Seite erneut, und Ihre
console.log()
-Anweisung sollte das gewünschte<p>
-Element zurückgeben. Puh! Ein weiterer Fehler behoben! Sie können Ihreconsole.log()
-Zeile jetzt löschen oder sie behalten, um später darauf zu verweisen — Ihre Wahl.
Hinweis: Weitere Einzelheiten zu diesem Fehler finden Sie auf unserer Referenzseite TypeError: "x" is (not) "y".
Syntaxfehler Runde drei
- Wenn Sie das Spiel jetzt noch einmal versuchen, sollten Sie mehr Erfolg haben — das Spiel sollte einwandfrei laufen, bis Sie das Spiel beenden, entweder indem Sie die richtige Zahl erraten oder alle Versuche aufgebraucht haben.
- An diesem Punkt schlägt das Spiel erneut fehl, und es wird derselbe Fehler ausgeworfen, den wir am Anfang bekamen — "TypeError: resetButton.addeventListener is not a function"! Allerdings wird diesmal angegeben, dass er aus Zeile 95 stammt.
- Betrachtet man Zeile 95, ist es einfach zu sehen, dass wir hier denselben Fehler gemacht haben. Wir müssen hier einfach
addeventListener
inaddEventListener
ändern. Machen Sie das jetzt.
Ein Logikfehler
An diesem Punkt sollte das Spiel einwandfrei ablaufen, jedoch werden Sie nach ein paar Durchläufen zweifellos feststellen, dass das Spiel immer 1 als die "zufällige" Zahl auswählt, die Sie erraten müssen. Definitiv nicht so, wie wir das Spiel ablaufen lassen wollen!
Es gibt definitiv ein Problem in der Spiel-Logik irgendwo — das Spiel gibt keinen Fehler zurück; es läuft einfach nicht richtig.
-
Suchen Sie nach der Variablen
randomNumber
und den Zeilen, in denen die Zufallszahl zuerst festgelegt wird. Die Instanz, die die zufällig zu erratende Zahl zu Beginn des Spiels speichert, sollte sich ungefähr in Zeile 47 befinden:jslet randomNumber = Math.floor(Math.random()) + 1;
-
Und die, die die Zufallszahl vor jedem folgenden Spiel generiert, sich in etwa in Zeile 114:
jsrandomNumber = Math.floor(Math.random()) + 1;
-
Um zu überprüfen, ob diese Zeilen tatsächlich das Problem sind, wenden wir uns erneut unserem Freund
console.log()
zu — fügen Sie die folgende Zeile direkt unter jeder der beiden obigen Zeilen ein:jsconsole.log(randomNumber);
-
Speichern und aktualisieren, dann spielen Sie ein paar Spiele — Sie sehen, dass
randomNumber
an jedem Punkt, an dem es in die Konsole geloggt wird, gleich 1 ist.
Die Logik durchgehen
Um dies zu beheben, überlegen wir, wie diese Zeile funktioniert. Zuerst rufen wir Math.random()
auf, welches eine zufällige Dezimalzahl zwischen 0 und 1 generiert, z.B. 0.5675493843.
Math.random();
Als nächstes übergeben wir das Ergebnis des Aufrufs von Math.random()
an Math.floor()
, das die übergebene Zahl auf die nächste ganze Zahl abrundet. Wir addieren dann 1 zu diesem Ergebnis:
Math.floor(Math.random()) + 1;
Das Abrunden einer zufälligen Dezimalzahl zwischen 0 und 1 ergibt immer 0, daher wird durch das Addieren von 1 immer 1 zurückgegeben. Wir müssen die Zufallszahl mit 100 multiplizieren, bevor wir sie abrunden. Folgendes würde uns eine Zufallszahl zwischen 0 und 99 geben:
Math.floor(Math.random() * 100);
Daher wollen wir 1 addieren, um eine Zufallszahl zwischen 1 und 100 zu erhalten:
Math.floor(Math.random() * 100) + 1;
Versuchen Sie, beide Zeilen so zu aktualisieren, speicheren Sie und aktualisieren Sie — das Spiel sollte jetzt wie beabsichtigt ablaufen!
Weitere häufige Fehler
Es gibt weitere häufige Fehler, auf die Sie in Ihrem Code stoßen werden. Dieser Abschnitt hebt die meisten von ihnen hervor.
Das Programm sagt immer, Sie hätten gewonnen, unabhängig von dem eingegebenen Tipp
Dies könnte ein weiteres Symptom der Vermischung von Zuweisungs- und Strenggleichheit-Operatoren sein. Wenn wir zum Beispiel diese Zeile innerhalb von checkGuess()
ändern würden:
if (userGuess === randomNumber) {
zu
if (userGuess = randomNumber) {
würde der Test immer true
zurückgeben, was dazu führen würde, dass das Programm meldet, dass das Spiel gewonnen wurde. Seien Sie vorsichtig!
SyntaxError: missing ) after argument list
Dieser Fall ist ziemlich einfach — er bedeutet im Allgemeinen, dass Sie die schließende Klammer am Ende eines Funktions-/Methodenaufrufs vergessen haben.
Hinweis: Weitere Einzelheiten zu diesem Fehler finden Sie auf unserer Referenzseite SyntaxError: missing ) after argument list.
SyntaxError: missing : after property id
Dieser Fehler bezieht sich normalerweise auf ein inkorrekt geformtes JavaScript-Objekt, aber in diesem Fall haben wir es geschafft, ihn auszulösen, indem wir
function checkGuess() {
in
function checkGuess( {
geändert haben. Dies hat dazu geführt, dass der Browser glaubt, dass wir versuchen, den Inhalt der Funktion als Argument in die Funktion zu übergeben. Seien Sie vorsichtig mit diesen Klammern!
SyntaxError: missing } after function body
Dies ist simpel — es bedeutet im Allgemeinen, dass Sie eine Ihrer geschweiften Klammern aus einer Funktion oder einer bedingten Struktur ausgelassen haben. Wir bekamen diesen Fehler, indem wir eine der schließenden geschweiften Klammern nahe dem Ende der Funktion checkGuess()
gelöscht haben.
SyntaxError: expected expression, got 'string' oder SyntaxError: string literal contains an unescaped line break
Diese Fehler bedeuten im Allgemeinen, dass Sie das Öffnungs- oder Schließungszeichen eines Zeichenkettenwertes weggelassen haben. Im ersten Fehler oben würde string durch das unerwartete Zeichen/Zeichenfolge ersetzt werden, das der Browser anstelle eines Anführungszeichens am Anfang einer Zeichenkette gefunden hat. Der zweite Fehler bedeutet, dass die Zeichenkette nicht mit einem Anführungszeichen beendet wurde.
Für alle diese Fehler denken Sie daran, wie wir die Beispiele, die wir in der Schritt-für-Schritt-Anleitung angesehen haben, behandelt haben. Wenn ein Fehler auftritt, schauen Sie sich die angegebene Zeilennummer an, gehen Sie zu dieser Zeile und sehen Sie, ob Sie erkennen können, was falsch ist. Bedenken Sie, dass der Fehler nicht zwangsläufig in dieser Zeile sein muss und auch, dass der Fehler nicht durch genau dasselbe Problem verursacht wird, das wir oben genannt haben!
Hinweis: Weitere Einzelheiten zu diesen Fehlern finden Sie auf unseren Referenzseiten SyntaxError: Unexpected token und SyntaxError: string literal contains an unescaped line break.
Zusammenfassung
Da haben wir sie also, die Grundlagen der Fehlersuche in einfachen JavaScript-Programmen. Es wird nicht immer so einfach sein, herauszufinden, was in Ihrem Code falsch ist, aber zumindest wird dies Ihnen einige Stunden Schlaf ersparen und es Ihnen ermöglichen, ein bisschen schneller voranzukommen, wenn die Dinge nicht richtig laufen, besonders in den frühen Phasen Ihrer Lernreise.
Siehe auch
- Es gibt viele andere Fehlerarten, die hier nicht aufgeführt sind; wir erstellen eine Referenz, die erklärt, was sie im Detail bedeuten — siehe das JavaScript-Fehlerreferenz.
- Wenn Sie auf Fehler in Ihrem Code stoßen, die Sie nach dem Lesen dieses Artikels nicht beheben können, können Sie Hilfe bekommen! Fragen Sie nach Hilfe in den Kommunikationskanälen. Sagen Sie uns, was Ihr Fehler ist, und wir werden versuchen, Ihnen zu helfen. Eine Auflistung Ihres Codes wäre ebenfalls nützlich.