JavaScript/Tutorials/Einstieg/Programmieren und Debuggen

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche

Informationen zu diesem Text

Lesedauer
45min
Schwierigkeitsgrad
einfach
Vorausgesetztes Wissen
keine

Programmieren beinhaltet immer auch die Suche nach Fehlern. In JavaScript erzeugen Fehler oft keinen Abbruch oder eine Fehlermeldung und sorgen erst viel später für Probleme, deren Ursache dann durch Debuggen herausgefunden werden muss.

In diesem Kapitel lernen Sie, wie Sie Scripte auf Programmierfehler überprüfen und debuggen können. Als wichtiges Entwicklungswerkzeug, das die JavaScript-Programmierung entscheidend erleichtert, verwenden wir die eingebaute Konsole.

Damit können Sie ...

Kontrollausgabe mit der Konsole[Bearbeiten]

Screenshot
Ansicht der Firebug-Konsole im Firefox Version 40

Die Konsole öffnet sich …

  1. über die Funktionstaste F12
  2. über die jeweiligen Menüs,
  3. oder aber durch eine der folgenden Tastenkombinationen:
    • Mozilla Firefox: unter Windows und Linux mit Strg + Umschalt + I, unter Mac mit Cmd + Opt + I
    • Google Chrome: unter Windows und Linux mit Strg + Umschalt + J, unter Mac mit Cmd + Opt + J
    • Microsoft Edge und Internet Explorer: F12 anschließend Strg + 2

Künftig wollen wir mit der Konsole …

  • Ergebnisse ausgeben,
  • Variablen untersuchen
  • und den JavaScript-Code in der Konsole selbst ändern und erneut ausführen.

Hinweis

Die im Frickl verwendeten Scripte „beißen“ sich mit der Console API. Sie können zwar die ausgabe mit console.log nutzen; die Ansicht des Codes ist aber nur umständlich möglich.
  1. Kopieren Sie die Beispiel-Scripte in Ihren Editor und speichern Sie sie als HTML-Dokument ab.
  2. Öffnen Sie das HTML-Dokument in Ihrem Browser.
  3. Öffnen Sie die Konsole mit F12!

Kontrollstrukturen[Bearbeiten]

Ein Programm ist nicht nur eine unveränderliche Kette von aufeinanderfolgenden Anweisungen, sondern soll auf Eingaben unterschiedlich reagieren. Dafür kann man bedingte Anweisungen verwenden, die bei Erfüllen einer Bedingung einen Anweisungsblock ausführen, bei Nichterfüllen nichts oder etwas anderes tun.

Verzweigung[Bearbeiten]

Das Schlimmste, was einem angehenden Software-Ingenieur passieren kann, ist, dass der kleine Bruder versucht, einen Blick auf unser Programm zu werfen. Deshalb bauen wir als nächsten Schritt nun eine Altersabfrage ein.

Wenn-dann-Bedingung mit if[Bearbeiten]

4. Eingabe von Namen und Alter ansehen …
 1 <!doctype html>
 2 <html>
 3 <head>
 4 <meta charset="utf-8">
 5 <title>4. Eingabe von Namen und Alter</title>
 6 </head>
 7 <body>
 8 <script>
 9     'use strict';
10       var name  = '';
11       var alter = '';
12       const erwachsen = 18;
13       name = prompt('Bitte geben Sie Ihren Namen ein!', name);
14       alter = prompt('Bitte geben Sie Ihr Alter ein!', alter);
15 
16       if (alter < erwachsen) {
17         console.log('Du kommst hier net rein!');
18       }
19 
20       else {
21         var ausgabe = `Hallo ${name}!`;
22         console.log(ausgabe);
23       }
24 </script>
25 </body>
26 </html>
Das Beispiel ähnelt dem letzten Beispiel. Allerdings wird eine weitere Variable alter deklariert und ebenfalls abgefragt. Dazu kommt eine Konstante erwachsen mit dem Wert 18. Eine Konstante ist eine Variable, deren Wert während des Programmablaufs nicht verändert werden kann.

In Zeile 12 wird mit mit einer Wenn-Dann-Bedingung überprüft, ob der in runden Klammern stehende Ausdruck (alter < erwachsen) richtig ist.

Falls ja, wird der in geschweiften Klammern stehende Anweisungsblock ausgeführt. Falls die Bedingung nicht zutrifft, wird der zweite Anweisungsblock ausgeführt und die Begrüßung ausgegeben. Diese Ausgabe findet nicht mehr mit alert() statt, sondern mit console.log().
Beachten Sie: Es ist nicht zwingend nötig, den ersten Anweisungsblock in geschweifte Klammern zu setzen, da er nur aus einer Zeile besteht. Aus Gründen der Übersichtlichkeit (und falls Sie später den Code erweitern) ist dies jedoch zu empfehlen.

Hinweis

  1. Kopieren Sie die Beispiel-Scripte in Ihren Editor und speichern Sie sie als HTML-Dokument ab.
  2. Öffnen Sie das HTML-Dokument in Ihrem Browser.
  3. Öffnen Sie die Konsole mit F12!

Mit einem Klick auf Konsole können Sie nun unser kleines Programm überprüfen:

Screenshot der Konsole des Edge 79

Nach der Eingabe der gewünschten Parameter erscheint nun die Begrüßung in der Konsole.

Der Winkel ist eine Kommandozeile, in der Sie mit console.log z.B. den Wert der Variablen name, bzw. Name ausgeben können.

Beachten Sie: Da die Variable Name nicht deklariert ist, wird ein Referenzfehler „geworfen“.
Screenshot der Konsole des Firefox 76

Ähnlich sieht die Lage im Firefox aus. Hier wird die Kommandozeile durch einen Doppelwinkel angezeigt.

Mit console.log können nicht nur Variablen und Konstanten, sondern auch komplexere Ausdrücke wie die Bedingung der If-Abfrage überprüft werden.

Die gesamte Zeile mit dem Schlüsselwort IF wirft einen Syntaxfehler; für den Ausdruck (alter < erwachsen) wird als Ergebnis false ausgegeben.




Computerprogramme tun genau das, was man ihnen sagt. Es wird überprüft, ob die Variable kleiner als der Wert von erwachsen ist. Was passiert aber, wenn Sie anstatt einer Zahl ein Wort (eine Zeichenkette = string) eingeben?

Information: Fehlende Typisierung in JavaScript

In JavaScript gibt es keine festgelegten Datentypen. Selbst wenn wir für eine Variable eine Zahl vorgeben, wird durch die Eingabe eines Buchstabens eine Zeichenkette daraus.
 var breite = 5 + 10;

 var breite = breite + 'px';
Auch bei diesem Beispiel wird die Variable breite durch die Verkettung mit dem String 'px' zu einem String, obwohl sie vorher vom Typ number war und ihr der Wert einer Addition zugewiesen wurde.


Verflixt, die Eingabe einer Zeichenkette überlistet unsere Wenn-Dann-Bedingung. Dies ist ein logischer Fehler, der sich nicht durch ein Debuggen auf formale Sytaxfehler, sondern nur durch Testen des Programms und der erwarteten Ausgaben finden lässt.

Eine Möglichkeit wäre es, den Ausdruck umzukehren (alter >= erwachsen) und die beiden Anweisungsblöcke zu vertauschen. Sie können aber auch überprüfen, ob die Variable alter eine gültige Zahl ist und dann ebenfalls den Ablehnungstext ausgeben.

5. Altersabfrage mit Gültigkeitsüberprüfung ansehen …
 1 'use strict';
 2   var name  = '',
 3       alter = '',
 4       ablehnungsText = 'Du kommst hier net rein!';
 5   const erwachsen = 18;
 6 
 7   name = prompt('Bitte geben Sie Ihren Namen ein!', name);
 8   alter = prompt('Bitte geben Sie Ihr Alter ein!', alter);
 9 
10   if (isNaN(alter)) {
11     console.log(ablehnungsText);
12   }
13 
14   else if (alter >= erwachsen) {
15     var ausgabe = `Hallo ${name}!`;
16     console.log(ausgabe);
17   }
18       
19   else {
20     console.log(ablehnungsText);
21   }
Wir fügen in Zeile 10 eine weitere bedingte Anweisung ein, die mittels der Funktion isNaN überprüft, ob die Variable alter keine gültige Zahl ist. Falls die Bedingung zutrifft, alter also keine gültige Zahl ist, wird der Ablehnungstext ausgegeben.

Ansonsten wird nach else if eine weitere bedingte Anweisung notiert, in der überprüft wird, ob alter kleiner oder größer/gleich als der Wert der Konstante erwachsen ist. Trifft die Bedingung zu, wird der Begrüßungstext ausgegeben; trifft sie nicht zu, folgt der Ablehnungstext.

Dieser Ablehnungstext ist jetzt, damit er nicht zweimal notiert werden muss, am Anfang des Skripts als Variable deklariert worden.

Test: Variablen vergleichen[Bearbeiten]

Oft sind es die kleinen Fehler, die man übersieht, auch wenn man sich den Code dreimal anschaut.

In diesem Script sollen die Variablen a und b verglichen werden. Anscheinend ist 23 wohl auch 42 !?![1]

Variablen vergleichen ansehen …
var a = 23;
var b = 42;
if (a = b) {
  alert('23 ist 42, q.e.d.');
}

Zumindest könnte man mit einem console.log(a) vor der if-Abfrage bemerken, dass der Inhalt von a noch stimmt, innerhalb dann aber den Inhalt von b angenommen hat, was nicht beabsichtigt war. Und so muss der Fehler zwischen den beiden console.log() sitzen.


Variablen vergleichen ansehen …
var a = 23;
var b = 42;
console.log(a, b);
if (a = b) {
  console.log(a, b);
  alert('23 ist 42, q.e.d.');
}


Verzweigung mit switch[Bearbeiten]

Mit if und else können Sie genau zwei Fälle unterscheiden. Wenn Sie feiner differenzieren, also zwischen mehreren Fällen unterscheiden wollen, können Sie zwar mehrere if-Abfragen hintereinander notieren, aber es gibt noch eine elegantere Möglichkeit: die Fallunterscheidung mit switch:

6. Altersabfrage mit Gültigkeitsüberprüfung ansehen …
 1 'use strict';
 2 var name  = '';
 3 var alter = '';
 4 var eingabe = '';
 5 var text = '';
 6 const erwachsen = 18;
 7 
 8 name = prompt('Bitte geben Sie Ihren Namen ein!', name);
 9 alter = prompt('Bitte geben Sie Ihr Alter ein!', alter);
10 
11 if (isNaN(alter)) {
12     eingabe = 'dumm';
13 } 
14 else if (alter < erwachsen) {
15     eingabe = 'jung';
16 } else {
17     eingabe = 'ok';
18 }
19 
20 switch (eingabe) {
21     case 'jung':
22         text ='Du bist leider zu jung!';
23         break;
24     case 'dumm':
25         text ='Sie sind leider zu dumm, eine Zahl einzugeben!';
26         break;
27     default:
28         text = `Hallo ${name}!`;
29         break;
30 }
31   
32 console.log(text);
In diesem Beispiel wird die eingegebene Variable alter überprüft und anhand dessen einer neuen Variable eingabe ein Wert zugewiesen.
In einer switch-Abfrage wird dieser Wert wieder abgefragt und ein entsprechender Text ausgegeben.

Schleifen[Bearbeiten]

Zu den wichtigsten Kontrollstrukturen gehören Schleifen (auch „Wiederholung“ oder englisch loop) mit denen Sie einen Anweisungs-Block – den sogenannten Schleifenrumpf oder Schleifenkörper – wiederholt durchlaufen, solange die Schleifenbedingung gültig bleibt bzw. als Abbruchbedingung nicht eintritt.

while[Bearbeiten]

Mit Hilfe von while-Schleifen wiederholen Sie Programmanweisungen beliebig oft, nämlich solange, wie die im Schleifenkopf formulierte Bedingung erfüllt ist. Solche Schleifen eignen sich dann, wenn Sie nicht wissen, wie oft die Schleife durchlaufen werden soll.


7. Wiederholung einer Anweisung mit While ansehen …
'use strict';
var zahl,
    text;

zahl = prompt('Bitte geben Sie eine Zahl ein!', zahl);

  while (zahl >= 1) {
	text = zahl + '- 1 = ' + (zahl-1);
	zahl = zahl -1;
	console.log(text);
  }
In diesem Beispiel wird von der eingegebenen Zahl zahl in einer Schleife solange eins subtrahiert, bis die Summe 0 erreicht ist. Der Rechenweg wird in der Variablen text gespeichert und dann mit console.log ausgegeben.


Beachten Sie: Die hier verwendeten Scripte verzichten auf jegliches HTML. Normalerweise werden einzelne Elemente im DOM herausgesucht und ihr Inhalt überschrieben (siehe auch: DOM-Tutorial: Ausgabefunktion). Wir wollten es hier aber bewusst einfach halten.

for[Bearbeiten]

Bei einer for-Schleife zählt der Computer von einer Anfangszahl bis zu einer Endzahl und wiederholt dabei jedes mal den Codeblock („Schleifenrumpf“) hinter dem for(...). Die aktuelle Zahl wird in eine Variable i („Iterator“) gesetzt, damit sie bei Bedarf in dem Codeblock Verwendung finden kann.

8. Zählschleife mit for ansehen …
'use strict';
var zahl,
    text;

confirm('Sind Sie bereit?');

for (var i = 1; i <= 10; i++) {
    zahl =  i * i;	  
    text = zahl +' = '+ i +' * '+ i ;
    console.log(text);
}
Sobald sie mit confirm() bestätigen, wird die Schleife ausgeführt.

Die Zählschleife wird insgesamt 10 mal durchlaufen, nämlich so oft, wie der Zähler, der in der Variablen i definiert und mit dem Wert 1 initialisiert wird, kleiner oder gleich 10 ist (Ausdruck i <= 10), wobei er bei jedem Schleifendurchlauf um 1 erhöht wird (Ausdruck i++). Die Zählvariable i wird mit sich selbst multipliziert und der Variable zahl zugewiesen.

Anschließend wird alles ausgegeben.

Man kann der Variablen auch einen anderen Namen geben (z. B. zaehler); konventionsgemäß nennt man sie aber meistens i, so wie auch hier in unserem Beispiel.

Ebenso ist es möglich, die Variable hinunter- statt hinaufzählen zu lassen (i-- statt i++). In diesem Fall muss man aber den Anfangs- und den Endwert anpassen – denn wenn i mit dem Wert 1 anfängt und dann immer heruntergezählt wird, dann wird die Bedingung i <= 10 immer zutreffen und die Schleife wird unendlich oft durchlaufen. (Anmerkung: In Wirklichkeit wird sie nicht unendlich oft durchlaufen, sondern „nur“ einige Milliarden Male, bis es zu einem sogenannten Überlauf kommt; in der Praxis macht dies für uns hier aber keinen Unterschied.)

Für einen Countdown müsste die entsprechende Zeile also wie folgt aussehen:

8. Countdown-Zählschleife mit for
// ... Rest genau wie oben ...

for (var i = 10; i >= 1; i--) {

// ... Rest genau wie oben ...

Fallen und Fehlerquellen[Bearbeiten]

  • runde oder geschweifte Klammern?
    Alle Klammern die geöffnet werden, müssen auch wieder geschlossen werden!
    Ist eine Klammer zuviel im Script-Code?
  • Hochkommata um Strings?
    Fehlt ein schließendes Hochkomma oder wird ein doppeltes Hochkomma durch ein einfaches Hochkomma geschlossen?
  • Bindestrich im Variablennamen?
    Wenn Sie eine Variable mit einem Bindestrich schreiben, wird aus ihrem Namen eine Zuweisung, da JavaScript den Bindestrich als Rechenoperator ansieht und versucht die beiden Teile der Variablen zu subtrahieren.
  • Groß- und Kleinschreibung
    Javascript ist case-sensitive, dass heißt, das nameVorname und namevorname unterschiedliche Variablen sind. Sie geben in der Konsole im strengen Modus eine Fehlermeldung.
    Empfehlung: Verwenden Sie das so genannte CamelCase, in dem jeweils der erste Buchstabe der einzelnen Bestandteile des Namens groß geschrieben wird.
    Beispiel:
    DiesIstEineVariable.
  • Schreibfehler in einer der DOM-Methoden?
    Vor allem Methoden wie getElementById werden oft falsch geschrieben. Hier hilft ein Web-Editor mit autocomplete, der Methoden und mehrmals verwendete Variablen automatisch vorschlägt.


Empfehlung: Debuggen anstatt Rumprobieren

Rumprobieren ist in der Regel allerdings nicht die effizienteste Methode um Fehlerursachen zu identifizieren. Wann immer irgendwas nicht funktioniert, sollte zunächst ein Blick auf die Konsole des Browsers geworfen werden. Dort finden Sie entsprechende Hinweise, um welche Art von Fehler es sich handelt, wie zum Beispiel …

  • ein Syntax Error, etwa wenn das Schließen einer Klammer vergessen wurde, oder
  • ein Reference Error, wenn du an einer Stelle versuchst über einen Bezeichner eine Variable zu referenzieren, die in dem jeweiligen Kontext (noch) nicht existiert (also wie mit event in deinem Frageposting), oder
  • ein Type Error, üblicherweise dadurch verursacht, dass an einer Stelle ein Objekt erwartet wird, aber statt dessen der primitive Wert undefined vorliegt, da die Übergabe vergessen wurde.

… sowie darüber hinaus auch immer eine Angabe dazu gegeben wird, an welcher Stelle, also in welcher Datei und in welcher Zeile der Fehler aufgetreten ist. Meistens genügt das schon, um den Fehler zu finden.

Manchmal funktioniert etwas aber auch nicht, ohne dass das Programm durch eine Ausnahme beendet wurde. In diesem Fall hilft die Eingrenzungstaktik, wobei man step by step diejenigen Teile des Programms auskommentiert, die wie gewünscht funktionieren, bis dann schließlich der Teil gefunden ist, der nicht funktioniert.

Eine weitere Möglichkeit ist das Setzen von Haltepunkten, die automatisch alle Variablen in der Konsole angeben. Dann ist entsprechend immer zu prüfen, ob die tatsächlichen Werte an einer Stelle mit den erwarteten Werten übereinstimmen. So kommt man der Fehlerursache Schritt für Schritt näher. ;-)


Quellen[Bearbeiten]

  1. Self-Forum: Wiki: Tutorial Grundlagen von Strings und Arrays vom 20.04.2017