Was ist schiefgelaufen? Fehlerbehebung in JavaScript
Als Sie im vorherigen Artikel das "Errate die Zahl"-Spiel erstellt haben, haben Sie möglicherweise festgestellt, dass es nicht funktioniert hat. Keine Sorge — dieser Artikel soll Sie davor bewahren, sich die Haare über solche Probleme zu raufen, 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 mit dem Schreiben von JavaScript. |
---|---|
Lernergebnisse: |
|
Fehlerarten
Im Allgemeinen gibt es beim Codieren zwei Hauptarten von Fehlern, auf die Sie stoßen werden:
- Syntaxfehler: Dies sind Rechtschreibfehler in Ihrem Code, die dazu führen, dass das Programm überhaupt nicht läuft oder mitten im Betrieb stoppt — normalerweise erhalten Sie auch einige Fehlermeldungen. Diese sind normalerweise in Ordnung zu beheben, solange Sie mit den richtigen Tools vertraut sind und wissen, was die Fehlermeldungen bedeuten!
- Logikfehler: Diese Fehler treten auf, wenn die Syntax eigentlich korrekt ist, der Code jedoch nicht das ist, was Sie beabsichtigt haben. Das bedeutet, dass das Programm erfolgreich läuft, jedoch falsche Ergebnisse liefert. Diese sind oft schwieriger zu beheben als Syntaxfehler, da normalerweise keine Fehlermeldung vorhanden ist, die Sie zur Fehlerquelle führt.
Okay, es ist nicht ganz so einfach — es gibt einige andere Unterscheidungsmerkmale, wenn Sie tiefer bohren. Aber die obigen Klassifizierungen genügen in diesem frühen Stadium Ihrer Karriere. Wir werden fortfahren, auf beide Arten zu schauen.
Ein fehlerhaftes Beispiel
Um anzufangen, kehren wir zu unserem Zahlratenspiel zurück — außer dass wir diesmal eine Version mit absichtlich eingeführten Fehlern untersuchen. Gehen Sie zu GitHub und erstellen Sie sich eine lokale Kopie von number-game-errors.html (siehe es hier live laufen).
- Öffnen Sie 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 auf die Schaltfläche "Vermutung absenden" klicken!
Hinweis: Es könnte durchaus sein, dass Sie Ihre eigene Version des Spielbeispiels haben, die nicht funktioniert, die Sie möglicherweise reparieren möchten! Wir möchten dennoch, dass Sie den Artikel mit unserer Version durcharbeiten, damit Sie die Techniken erlernen, die wir hier vermitteln. Dann können Sie zurückgehen und versuchen, Ihr Beispiel zu reparieren.
An diesem Punkt lassen Sie uns die Entwicklerkonsole konsultieren, um zu sehen, ob sie Syntaxfehler meldet, und versuchen Sie, sie zu beheben. Sie erfahren im folgenden Abschnitt, 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 dies in Ihrem Browser öffnen, folgen Sie dem vorherigen Link, um herauszufinden, wie). Noch nützlicher ist, dass die Konsole Ihnen Fehlermeldungen gibt, wenn ein Syntaxfehler in das JavaScript gespeist wird, das in die JavaScript-Engine des Browsers eingegeben wird. Lassen Sie uns nun auf Jagd gehen.
-
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 ähnlich der folgenden 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 etwas darüber, was schiefgelaufen ist. - Der zweite Teil,
number-game-errors.html:87:19
, sagt uns, wo im Code der Fehler herkommt: 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", 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 über die korrekte Schreibweise eines Syntax-Teils nicht sicher sind, ist es oft gut, das Feature auf MDN nachzuschlagen. 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 etwas Zeit an dieser Stelle zu sparen:
addEventListener()
. -
Beim Betrachten dieser Seite scheint der Fehler darin zu bestehen, dass wir den Funktionsnamen falsch geschrieben haben! Denken Sie daran, dass JavaScript die Groß- und Kleinschreibung beachtet. Jede Abweichung in Schreibweise oder Groß-/Kleinschreibung führt zu einem Fehler. Das Ändern von
addeventListener
zuaddEventListener
sollte dies beheben. Machen Sie dies jetzt.
Hinweis: Siehe unsere TypeError: "x" ist keine Funktion Referenzseite für weitere Details zu diesem Fehler.
Syntaxfehler Runde zwei
-
Speichern Sie Ihre Seite und aktualisieren Sie sie, und der Fehler sollte verschwunden sein.
-
Wenn Sie nun versuchen, eine Vermutung einzugeben und die Schaltfläche "Vermutung absenden" zu drücken, wird ein weiterer Fehler angezeigt!
-
Diesmal wird der gemeldete Fehler angezeigt als:
Uncaught TypeError: can't access property "textContent", lowOrHi is null
Abhängig vom verwendeten Browser sehen Sie möglicherweise eine andere Meldung. Die oben genannte Meldung wird Ihnen Firefox anzeigen, aber Chrome würde Ihnen beispielsweise folgendes zeigen:
Uncaught TypeError: Cannot set properties of null (setting 'textContent')
Es ist der gleiche Fehler, aber verschiedene Browser beschreiben ihn auf unterschiedliche Weise.
Hinweis: Dieser Fehler trat nicht auf, sobald die Seite geladen wurde, weil dieser Fehler innerhalb einer Funktion auftrat (innerhalb des
checkGuess() { }
Blocks). Wie Sie in unserem späteren Funktionen-Artikel im Detail erfahren werden, läuft der Code innerhalb der Funktionen in einem separaten Scope als der Code außerhalb von Funktionen. In diesem Fall wurde der Code nicht ausgeführt und der Fehler wurde nicht angezeigt, bis diecheckGuess()
Funktion durch Zeile 87 ausgeführt wurde. -
Die in der Fehlernachricht angegebene Zeilennummer ist 79. Schauen Sie sich Zeile 79 an, und Sie sehen den folgenden Code:
jslowOrHi.textContent = "Last guess was too high!";
-
Diese Zeile versucht, die
textContent
Eigenschaft derlowOrHi
Variable auf einen Text-String zu setzen, aber es funktioniert nicht, weillowOrHi
nicht das enthält, was es soll. Lassen Sie uns sehen, warum das so ist — versuchen Sie, nach anderen Instanzen vonlowOrHi
im Code zu suchen. Die früheste Instanz finden Sie in Zeile 51:jsconst lowOrHi = document.querySelector("lowOrHi");
-
An diesem Punkt versuchen wir, die Variable einen Verweis auf ein Element im HTML-Dokument enthalten zu lassen. Lassen Sie uns sehen, was die Variable enthält, nachdem diese Zeile ausgeführt wurde. Fügen Sie in Zeile 54 den folgenden Code ein:
jsconsole.log(lowOrHi);
Dieser Code wird den Wert von
lowOrHi
in der Konsole ausgeben, nachdem wir versucht haben, ihn in Zeile 51 festzulegen. Sieheconsole.log()
für mehr Informationen. -
Speichern und aktualisieren Sie, und Sie sollten nun das Ergebnis von
console.log()
in Ihrer Konsole sehen. Tatsächlich ist der Wert vonlowOrHi
zu diesem Zeitpunktnull
, und das stimmt mit der Firefox-FehlermeldunglowOrHi is null
überein. Da gibt es definitiv ein Problem mit Zeile 51. Dernull
Wert bedeutet "nichts" oder "kein Wert". Unser Code, umlowOrHi
auf ein Element zu setzen, läuft also schief. -
Lassen Sie uns nachdenken, 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. Weiter oben in unserer Datei können wir den betreffenden Absatz finden:html<p class="lowOrHi"></p>
-
Wir brauchen hier also einen Klassenselektor, der mit einem Punkt (
.
) beginnt, aber der Selektor, der derquerySelector()
Methode in Zeile 51 übergeben wird, hat keinen Punkt. Das könnte das Problem sein! Versuchen Sie,lowOrHi
zu.lowOrHi
in Zeile 51 zu ändern. -
Versuchen Sie, zu speichern und neu zu laden, und Ihre
console.log()
Anweisung sollte nun das gewünschte<p>
Element zurückgeben. Puh! Ein weiterer Fehler behoben! Sie können nun Ihreconsole.log()
Zeile löschen oder sie behalten, um später darauf Bezug zu nehmen — Ihre Wahl.
Hinweis: Siehe unsere TypeError: "x" is (not) "y" Referenzseite für weitere Details zu diesem Fehler.
Syntaxfehler Runde drei
- Wenn Sie jetzt versuchen, das Spiel erneut zu spielen, sollten Sie mehr Erfolg haben — das Spiel sollte bis zum Ende durchgespielt werden, es sei denn, Sie erraten die richtige Zahl oder die Versuche sind aufgebraucht.
- An diesem Punkt fällt das Spiel erneut aus, und der gleiche Fehler wird ausgegeben, den wir am Anfang hatten — "TypeError: resetButton.addeventListener is not a function"! Allerdings wird dieses Mal die Zeile 95 angegeben.
- Wenn Sie sich Zeile 95 ansehen, ist es leicht zu sehen, dass wir hier denselben Fehler gemacht haben. Wir müssen
addeventListener
erneut zuaddEventListener
ändern. Tun Sie das jetzt.
Ein Logikfehler
An diesem Punkt sollte das Spiel in Ordnung durchlaufen, jedoch werden Sie nachdem Sie ein paar Mal gespielt haben, zweifellos bemerken, 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 Logik des Spiels — das Spiel liefert keinen Fehler zurück; es läuft einfach nicht richtig.
-
Suchen Sie die
randomNumber
Variablen und die Zeilen, in denen die Zufallszahl zuerst gesetzt wird. Die Instanz, die die zufällige Zahl speichert, die wir zu Beginn des Spiels erraten wollen, sollte um die Zeile 47 liegen:jslet randomNumber = Math.floor(Math.random()) + 1;
-
Und die, die die Zufallszahl vor jedem nachfolgenden Spiel erzeugt, ist 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 an unseren Freund
console.log()
— fügen Sie folgende Zeile direkt nach jeder der oben genannten Zeilen ein:jsconsole.log(randomNumber);
-
Speichern und aktualisieren Sie, dann spielen Sie ein paar Spiele — Sie werden sehen, dass
randomNumber
gleich 1 zu jedem Zeitpunkt ist, an dem es in der Konsole protokolliert wird.
Die Logik durchgehen
Um dies zu beheben, überlegen wir, wie diese Zeile funktioniert. Zunächst rufen wir Math.random()
auf, die eine zufällige Dezimalzahl zwischen 0 und 1 generiert, z.B. 0.5675493843.
Math.random();
Als Nächstes geben wir das Ergebnis der Ausführung von Math.random()
durch 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;
Ein zufälliges Dezimal zwischen 0 und 1 abzurunden, wird immer 0 zurückgeben, also wird das Hinzufügen von 1 dazu immer 1 zurückgeben. Wir müssen die zufällige Zahl mit 100 multiplizieren, bevor wir sie abrunden. Das folgende würde uns eine zufällige Zahl zwischen 0 und 99 geben:
Math.floor(Math.random() * 100);
Daher wollen wir 1 hinzufügen, um uns eine zufällige Zahl zwischen 1 und 100 zu geben:
Math.floor(Math.random() * 100) + 1;
Versuchen Sie, beide Zeilen auf diese Weise zu aktualisieren, dann speichern und aktualisieren Sie — das Spiel sollte nun wie beabsichtigt laufen!
Andere häufige Fehler
Es gibt andere häufige Fehler, auf die Sie in Ihrem Code stoßen werden. Dieser Abschnitt hebt die meisten davon hervor.
Das Programm sagt immer, dass Sie gewonnen haben, unabhängig von der eingegebenen Vermutung
Dies könnte ein weiteres Symptom für die Verwechslung der Zuweisungs- und der strikten Gleichheitsoperatoren sein. Zum Beispiel, wenn wir diese Zeile in checkGuess()
ändern würden:
if (userGuess === randomNumber) {
zu
if (userGuess = randomNumber) {
würde der Test immer true
zurückgeben und das Programm berichten, dass das Spiel gewonnen wurde. Seien Sie vorsichtig!
SyntaxError: missing ) after argument list
Dieser ist ziemlich einfach — er bedeutet im Allgemeinen, dass Sie die schließende Klammer am Ende eines Funktions-/Methodenaufrufs vergessen haben.
Hinweis: Siehe unsere SyntaxError: missing ) after argument list Referenzseite für weitere Details zu diesem Fehler.
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 durch Ändern von
function checkGuess() {
in
function checkGuess( {
zu verursachen. Dies hat den Browser denken lassen, 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 einfach — es bedeutet im Allgemeinen, dass Sie eine Ihrer geschweiften Klammern aus einer Funktion oder Bedingungsstruktur vergessen haben. Wir haben diesen Fehler erhalten, indem 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 im Allgemeinen, dass Sie das öffnende oder schließende Anführungszeichen einer Zeichenfolgewert-Literal weggelassen haben. Bei dem ersten Fehler würde string durch das unerwartete Zeichen ersetzt, das der Browser anstelle eines Anführungszeichens zu Beginn einer Zeichenfolge gefunden hat. Der zweite Fehler bedeutet, dass die Zeichenfolge nicht mit einem Anführungszeichen beendet wurde.
Für all diese Fehler denken Sie darüber nach, wie wir die Beispiele angegangen sind, die wir im Durchlauf betrachtet haben. Wenn ein Fehler auftritt, schauen Sie sich die Ihnen gegebene Zeilennummer an, gehen Sie zu dieser Zeile und sehen Sie, ob Sie sehen können, was falsch ist. Beachten Sie, dass der Fehler nicht unbedingt in dieser Zeile vorliegen muss, und auch, dass der Fehler nicht unbedingt durch genau dasselbe Problem verursacht wurde, das oben zitiert wurde!
Hinweis: Siehe unsere SyntaxError: Unexpected token und SyntaxError: string literal contains an unescaped line break Referenzseiten für mehr Details zu diesen Fehlern.
Zusammenfassung
Da haben wir sie, 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 ein paar Stunden Schlaf ersparen und Ihnen ermöglichen, ein bisschen schneller voranzukommen, wenn Dinge nicht richtig laufen, besonders in den frühen Stadien Ihrer Lernreise.
Siehe auch
- Es gibt viele andere Arten von Fehlern, die hier nicht aufgeführt sind; wir erstellen eine Referenz, die erklärt, was sie im Detail bedeuten — siehe die JavaScript-Fehlerreferenz.
- Wenn Sie auf einen Fehler in Ihrem Code stoßen, den Sie nach dem Lesen dieses Artikels nicht wissen, wie Sie ihn beheben können, können Sie Hilfe erhalten! Fragen Sie über die Kommunikationskanäle nach Hilfe. Sagen Sie uns, was Ihr Fehler ist, und wir werden versuchen, Ihnen zu helfen. Ein Listing Ihres Codes wäre auch nützlich.