Was ist schiefgelaufen? Fehlerbehebung in JavaScript
Als Sie das Spiel "Errate die Zahl" im vorherigen Artikel erstellt haben, haben Sie vielleicht festgestellt, dass es nicht funktioniert hat. Keine Sorge — dieser Artikel soll Ihnen helfen, Lösungen für solche Probleme zu finden, 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 CSS-Grundlagen, grundlegende Erfahrung im Schreiben von JavaScript. |
---|---|
Lernziele: |
|
Fehlerarten
Im Allgemeinen gibt es zwei Hauptfehlerarten, auf die Sie stoßen werden, wenn Sie etwas im Code falsch machen:
- Syntaxfehler: Dies sind Rechtschreibfehler in Ihrem Code, die dazu führen, dass das Programm überhaupt nicht ausgeführt wird oder mitten in der Ausführung stoppt — in der Regel erhält man auch einige Fehlermeldungen. Diese sind normalerweise nicht zu schwer zu beheben, solange Sie mit den richtigen Werkzeugen vertraut sind und die Fehlermeldungen verstehen!
- Logikfehler: Dies sind Fehler, bei denen die Syntax tatsächlich 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 schwerer zu beheben als Syntaxfehler, da es normalerweise keine Fehlermeldung gibt, die Sie zur Fehlerquelle führt.
Okay, es ist nicht ganz so einfach — es gibt einige andere Unterscheidungen, wenn Sie tiefer in die Materie eintauchen. Aber die obigen Klassifizierungen reichen zu diesem frühen Zeitpunkt in Ihrer Karriere aus. Wir werden uns diese beiden Typen im Folgenden genauer ansehen.
Ein fehlerhaftes Beispiel
Um loszulegen, kehren wir zu unserem Zahlenspiel zurück — außer dass wir diesmal eine Version untersuchen, die einige absichtliche Fehler enthält. Gehen Sie zu GitHub und erstellen Sie sich eine lokale Kopie von number-game-errors.html (siehe es hier live ausführen).
- Öffnen Sie die lokale Kopie in Ihrem bevorzugten Texteditor und Browser.
- Versuchen Sie das Spiel zu spielen — Sie werden feststellen, dass es nicht funktioniert, wenn Sie die Schaltfläche "Tipp abschicken" drücken!
Hinweis: Sie könnten auch Ihre eigene Version des Spiels haben, die nicht funktioniert und die Sie reparieren möchten! Dennoch möchten wir, dass Sie den Artikel mit unserer Version durchgehen, damit Sie die hier vermittelten Techniken lernen können. Danach können Sie versuchen, Ihr eigenes Beispiel zu reparieren.
An diesem Punkt schauen wir uns die Entwicklerkonsole an, um zu sehen, ob sie Syntaxfehler meldet, und dann versuchen wir, sie zu beheben. Sie lernen unten, wie das geht.
Beheben von Syntaxfehlern
Früher im Kurs haben wir Sie dazu gebracht, einige einfache JavaScript-Befehle in die JavaScript-Konsole der Entwickler-Tools einzutippen (wenn Sie sich nicht mehr erinnern, wie Sie diese in Ihrem Browser öffnen, folgen Sie dem Link, um herauszufinden, wie). Was noch nützlicher ist, ist, dass die Konsole Ihnen Fehlermeldungen gibt, wenn ein Syntaxfehler im JavaScript vorliegt, das an die JavaScript-Engine des Browsers übergeben wird. Lassen Sie uns jetzt danach suchen.
-
Wechseln Sie zu dem Tab, in dem Sie
number-game-errors.html
geöffnet haben, und öffnen Sie Ihre JavaScript-Konsole. Sie sollten eine Fehlermeldung wie die folgende sehen: -
Die erste Zeile der Fehlermeldung ist:
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, 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 sagt "guessSubmit.addeventListener is not a function". Das 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 der korrekten Schreibweise eines Syntaxelements nicht sicher sind, ist es oft gut, das Feature auf MDN nachzuschlagen. Der beste Weg, dies derzeit zu tun, ist, mit Ihrem bevorzugten Suchanbieter nach "mdn name-of-feature" zu suchen. Hier ist eine Abkürzung, um Ihnen in diesem Fall etwas Zeit zu sparen:
addEventListener()
. -
Beim Betrachten dieser Seite scheint der Fehler zu sein, dass wir den Funktionsnamen falsch geschrieben haben! Denken Sie daran, dass JavaScript case-sensitiv ist, so dass bereits ein kleiner Unterschied in der Schreibweise oder Groß-/Kleinschreibung zu einem Fehler führt. Das Ändern von
addeventListener
zuaddEventListener
sollte dies beheben. Tun Sie das jetzt.
Hinweis: Weitere Details 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 abzugeben und die Schaltfläche Tipp abschicken zu drücken, sehen Sie einen weiteren Fehler!
-
Diesmal wird der folgende Fehler gemeldet:
Uncaught TypeError: can't access property "textContent", lowOrHi is null
Abhängig vom verwendeten Browser sehen Sie hier möglicherweise eine andere Meldung. Die obige Meldung zeigt, was Firefox Ihnen anzeigt, wohingegen Chrome Ihnen folgendes zeigt:
Uncaught TypeError: Cannot set properties of null (setting 'textContent')
Es handelt sich um denselben Fehler, aber verschiedene Browser beschreiben ihn auf unterschiedliche Weise.
Hinweis: Dieser Fehler trat nicht sofort beim Laden der Seite auf, weil dieser Fehler innerhalb einer Funktion (innerhalb des
checkGuess() { }
Blocks) auftrat. Wie Sie ausführlicher in unserem späteren Artikel zu Funktionen lernen werden, wird Code innerhalb von Funktionen in einem separaten Gültigkeitsbereich als Code außerhalb von Funktionen ausgeführt. In diesem Fall wurde der Code nicht ausgeführt und der Fehler nicht geworfen, bis diecheckGuess()
-Funktion durch Zeile 87 ausgeführt wurde. -
Die in der Fehlermeldung angegebene Zeilennummer ist 79. Schauen Sie sich Zeile 79 an, und Sie werden den folgenden Code sehen:
jslowOrHi.textContent = "Last guess was too high!";
-
Diese Zeile versucht, die
textContent
-Eigenschaft der VariablelowOrHi
auf eine Textzeichenkette festzulegen, aber es funktioniert nicht, weillowOrHi
nicht das enthält, was es sollte. Finden wir heraus, warum das so ist — versuchen Sie, nach anderen Instanzen vonlowOrHi
im Code zu suchen. Die früheste Instanz befindet sich 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. Schauen wir uns an, was die Variable nach dieser Zeile enthält. Fügen Sie folgende Zeile in Zeile 54 ein:
jsconsole.log(lowOrHi);
Dieser Code wird den Wert von
lowOrHi
in der Konsole ausgeben, nachdem wir ihn in Zeile 51 gesetzt haben. Weitere Informationen finden Sie in der Dokumentation zuconsole.log()
. -
Speichern und aktualisieren Sie die Seite, und Sie sollten jetzt das
console.log()
Ergebnis in Ihrer Konsole sehen.Sicher genug,
lowOrHi
's Wert ist an diesem Punktnull
, und das stimmt mit der Firefox-FehlermeldunglowOrHi is null
. Also gibt es definitiv ein Problem mit Zeile 51. Dernull
Wert bedeutet "nichts" oder "kein Wert". Unser Code, umlowOrHi
auf ein Element zu setzen, geht also schief. -
Überlegen wir, was das Problem sein könnte. Zeile 51 verwendet eine
document.querySelector()
Methode, um einen Verweis auf ein Element zu erhalten, indem es mit einem CSS-Selektor ausgewählt wird. Wenn wir weiter oben in unserer Datei nachsehen, finden wir den fraglichen Absatz:html<p class="lowOrHi"></p>
-
Wir benötigen also einen Klassenselektor hier, der mit einem Punkt (
.
) beginnt, aber der Selektor, der in diequerySelector()
Methode in Zeile 51 übergeben wird, hat keinen Punkt. Das könnte das Problem sein! Versuchen SielowOrHi
in.lowOrHi
in Zeile 51 zu ändern. -
Versuchen Sie es zu speichern und aktualisieren, und Ihre
console.log()
Anweisung sollte nun das<p>
Element zurückgeben, das wir wollen. Puh! Ein weiterer Fehler behoben! Sie können Ihreconsole.log()
Zeile jetzt löschen oder zum späteren Nachschlagen aufbewahren — Ihre Wahl.
Hinweis: Weitere Details zu diesem Fehler finden Sie auf unserer Referenzseite TypeError: "x" is (not) "y".
Syntaxfehler Runde drei
- Wenn Sie das Spiel jetzt noch einmal versuchen zu spielen, sollten Sie mehr Erfolg haben — das Spiel sollte vollständig funktionieren, bis Sie das Spiel beenden, entweder indem Sie die richtige Zahl raten oder indem Ihnen die Tipps ausgehen.
- An dieser Stelle scheitert das Spiel wieder, und derselbe Fehler, den wir am Anfang hatten — "TypeError: resetButton.addeventListener is not a function"! Dieses Mal wird er jedoch als aus Zeile 95 kommend aufgelistet.
- Wenn wir uns Zeile 95 ansehen, ist es leicht zu sehen, dass wir hier denselben Fehler gemacht haben. Wir müssen nur
addeventListener
wieder inaddEventListener
ändern. Tun Sie das jetzt.
Ein Logikfehler
An diesem Punkt sollte das Spiel reibungslos durchlaufen, jedoch werden Sie nach ein paar Spielen zweifellos feststellen, dass das Spiel immer 1 als die "zufällige" Zahl wählt, die Sie erraten müssen. Definitiv nicht ganz so, wie wir wollen, dass das Spiel abläuft!
Es gibt definitiv ein Problem in der Spieldokumentation irgendwo — das Spiel gibt zwar keinen Fehler zurück; es funktioniert einfach nicht richtig.
-
Suchen Sie die
randomNumber
Variable und die Zeilen, in denen die Zufallszahl zunächst festgelegt wird. Die Instanz, die die Zufallszahl speichert, die wir am Anfang des Spiels erraten müssen, sollte sich um Zeile 47 befinden:jslet randomNumber = Math.floor(Math.random()) + 1;
-
Und diejenige, die die Zufallszahl vor jedem weiteren Spiel generiert, ist um Zeile 114:
jsrandomNumber = Math.floor(Math.random()) + 1;
-
Um zu überprüfen, ob diese Zeilen tatsächlich das Problem sind, wenden wir uns wieder an unseren Freund
console.log()
— fügen Sie die folgende Zeile direkt unter den beiden obigen Zeilen ein:jsconsole.log(randomNumber);
-
Speichern und aktualisieren Sie dann, und spielen Sie ein paar Spiele — Sie werden sehen, dass
randomNumber
zu jedem Zeitpunkt, an dem es in der Konsole protokolliert wird, gleich 1 ist.
Durch die Logik arbeiten
Um das zu beheben, überlegen wir, wie diese Zeile funktioniert. Zunächst rufen wir Math.random()
auf, das eine zufällige Dezimalzahl zwischen 0 und 1 erzeugt, z. B. 0.5675493843.
Math.random();
Als nächstes geben wir das Ergebnis des Aufrufs von Math.random()
durch Math.floor()
, das die übergebene Zahl auf die nächste ganze Zahl abrundet. Dann fügen wir diesem Ergebnis 1 hinzu:
Math.floor(Math.random()) + 1;
Das Abrunden einer zufälligen Dezimalzahl zwischen 0 und 1 nach unten wird immer 0 zurückgeben, daher wird das Hinzufügen von 1 dazu immer 1 zurückgeben. Wir müssen die Zufallszahl mit 100 multiplizieren, bevor wir es abrunden. Das Folgende würde uns eine Zufallszahl zwischen 0 und 99 geben:
Math.floor(Math.random() * 100);
Daher wollen wir 1 hinzufügen, um uns eine Zufallszahl zwischen 1 und 100 zu geben:
Math.floor(Math.random() * 100) + 1;
Versuchen Sie, beide Zeilen so zu aktualisieren, speichern Sie dann und aktualisieren Sie — das Spiel sollte jetzt so abgespielt werden, wie wir es beabsichtigen!
Andere häufige Fehler
Es gibt andere häufige Fehler, auf die Sie in Ihrem Code stoßen können. Dieser Abschnitt hebt die meisten davon hervor.
Das Programm sagt immer, dass Sie gewonnen haben, unabhängig von dem Tipp, den Sie eingeben
Dies könnte ein weiteres Symptom des Verwechselns von Zuweisungs- und Strikte-Gleichheits-Operatoren sein. Zum Beispiel, wenn wir diese Zeile innerhalb von checkGuess()
ändern würden:
if (userGuess === randomNumber) {
zu
if (userGuess = randomNumber) {
würde der Test immer true
zurückgeben und das Programm veranlassen, dass das Spiel gewonnen wurde. Seien Sie vorsichtig!
SyntaxError: missing ) after argument list
Dieser ist ziemlich einfach — er bedeutet normalerweise, dass Sie die schließende Klammer am Ende eines Funktions-/Methodenaufrufs vergessen haben.
Hinweis: Weitere Details 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 falsch formatiertes JavaScript-Objekt, aber in diesem Fall ist er aufgetreten, als wir
function checkGuess() {
in
function checkGuess( {
Änderten. Dies hat den Browser veranlasst zu denken, dass wir versuchen, den Inhalt der Funktion als Argument an die Funktion zu übergeben. Seien Sie vorsichtig mit diesen Klammern!
SyntaxError: missing } after function body
Dies ist einfach — es bedeutet normalerweise, dass Sie eine Ihrer geschweiften Klammern von einer Funktion oder einer Bedingungsstruktur vergessen haben. Wir hatten diesen Fehler, als wir eine der schließenden geschweiften Klammern am Ende der checkGuess()
-Funktion gelöscht haben.
SyntaxError: expected expression, got 'string' oder SyntaxError: string literal contains an unescaped line break
Diese Fehler bedeuten in der Regel, dass Sie das Anfangs- oder Endzeichen eines Zeichenfolgenwerts weggelassen haben. Im ersten obigen Fehler würde string durch das unerwartete Zeichen/die unerwarteten Zeichen ersetzt, die der Browser anstelle eines Anfangs-Zitatzeichens für eine Zeichenfolge gefunden hat. Der zweite Fehler bedeutet, dass die Zeichenkette nicht mit einem Anführungszeichen beendet wurde.
Für all diese Fehler denken Sie daran, wie wir die Beispiele angegangen sind, die wir im Rundgang betrachtet haben. Wenn ein Fehler auftritt, schauen Sie sich die Zeilennummer an, die Ihnen gegeben wurde, gehen Sie zu dieser Zeile und sehen Sie, ob Sie den Fehler erkennen können. Beachten Sie, dass der Fehler nicht unbedingt in dieser Zeile sein muss und dass der Fehler möglicherweise nicht durch genau dasselbe Problem verursacht wird, das wir oben geschildert haben!
Hinweis: Weitere Details 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, die Grundlagen zur Fehlererkennung in einfachen JavaScript-Programmen. Es wird nicht immer so einfach sein, herauszufinden, was in Ihrem Code falsch ist, aber zumindest wird Ihnen das ein paar Stunden Schlaf ersparen und es Ihnen ermöglichen, ein bisschen schneller voranzukommen, wenn etwas nicht richtig läuft, besonders in den Anfangsstadien Ihrer Lernreise.
Siehe auch
- Es gibt viele andere Arten von Fehlern, die hier nicht aufgelistet sind; wir erstellen eine Referenz, die erklärt, was sie im Detail bedeuten — siehe die JavaScript-Fehlerreferenz.
- Wenn Sie beim Lesen dieses Artikels auf Fehler in Ihrem Code stoßen, die Sie nicht beheben können, können Sie Hilfe bekommen! Bitten Sie um Hilfe auf den Kommunikationskanälen. Sagen Sie uns, was Ihr Fehler ist, und wir werden versuchen, Ihnen zu helfen. Eine Auflistung Ihres Codes wäre auch hilfreich.