JavaScript Artikel: JavaScript Debugging
von Jan Winkler
Das größte Problem eines JavaScript-Entwicklers ist immer dann, wenn ein Fehler auftritt. Aber wie findet man Fehler und wie behandelt man sie?
Am wichtigsten ist es erstmal den Fehler selbst zu erkennen und heraus zu finden, woran es liegt, dass das Script nicht macht, was es soll. Als erstes sollte also die Stelle (Zeile, Zeichen) sowie der Fehlertyp oder die Fehlermeldung herausgefunden werden. Diese Informationen liefert uns meist der Browser mit. Bei Microsoft erfährt man sie, wenn sie nicht sofort angezeigt wird, indem man in der Statusleiste auf das kleine Ausrufezeichen-Icon klickt. Bei Netscape durch die Eingabe von 'javascript:' in die Adresszeile.

Darstellung: Fehlericon des Internet Explorer
Anhand der gegebenen Informationen können Sie dann den Fehler bzw. die Stelle an der dieser aufgetreten ist finden.

Darstellung: Fehlermeldung im Internet Explorer

Darstellung: Fehlermeldung im Netscape Navigator

Darstellung: Fehlermeldung im Opera
Ist ein Fehler aufgetreten und die Stelle ausgemacht, wird mit der Behebung des Problems begonnen. Anhand der Fehlermeldung wissen wir in etwa, was zu tun ist. JavaScript selbst beschreibt mehrere Fehlertypen:
Fehler beim Konvertieren eines Objektes. (z.B. Array zu Error)
Überprüfen Sie, ob bzw. wie es möglich ist das Objekt in einen anderen Typ zu konvertieren. Unter Umständen geht das nicht automatisch sonder muss eine spezielle Funktion verwendet werden.
Überschreitung des Bereiches. (z.B. new Array(-12);)
Dieser Fehlertyp hat meist etwas mit Zahlen zu tun. Überprüfen Sie, ob evtl. Bereiche über- oder unterschritten werden. Arrays können z.B. keine negativen Indexe erhalten und Zahlen sollten nicht über das 32 Bit-System hinaus gehen.
Referenzfehler. (z.B. a += c; wenn c undefiniert ist)
Tritt meist bei Variablen mit null-Zeiger auf. Prüfen Sie ob alle Variablen und Objekte initialisiert bzw. mit einem Wert belegt sind, bevor sie anderweitig verwendet werden.
Fehler bei einer Regular Expression. (z.B. abc//ii)
Überprüfen Sie die verwendeten regulären Ausdrücke auf ihre Richtigkeit. Eventuell sollten Sie auch bedenken, dass manche Browser mit einigen sehr spezialisierten regulären Ausdrücken nicht klar kommen könnten.
Fehler im Syntax. (z.B. eval('x:=y");)
Überprüfen Sie ob die Schreibweise Ihres Scriptes korrekt ist. Schauen Sie, ob alle Klammern, Semikolons und Anführungszeichen richtig gesetzt sind.
Fehler im Typ.
Überprüfen Sie die verwendeten Typen und evtl. eigene Objekte auf ihre Richtigkeit.
URI-Fehler. (z.B. #0)
Überprüfen Sie Referenzen auf externe Quellen (Link, extere Scripte, CSS, Bilder, ...) und schauen Sie ob evtl. Dateien gesucht werden aber nicht vorhanden sind.
Da es eine vielzahl von möglichen Fehlern gibt und es sicher Jahre dauern würde alle zu beschreiben, sollen jetzt kurz die TOP 5 der häufigsten JavaScript-Fehler aufgezählt werden:
Sicher einer der häufigsten Fehler ist das Vergessen bzw. Falsch-Setzten von Anführungszeichen.Beachten Sie, dass das öffnende und schliesende Anführungszeichen das gleiche sein müssen und vergessen Sie nicht weitere Anführungszeichen innerhalb des Textes als Sonderzeichen (\' bzw. \") zu markieren. Beispiel:
alert(Sage diesen Text an);
alert('Das ist Peter's neues Buch!');
Vergewissern Sie sich, dass alle Klammern korrekt gesetzt sind. So gehören z.B. um if-, for- oder while-Bedingungen (runde) Klammern. Beim Funktionsaufruf werden runde Klammern erwartet. Es darf nicht zu viele Klammern geben. Beispiel:
machwas(};
if a == 1 { machwas() }
{machwas();}}
Kein Grund für einen Fehler, aber meist einer für ein nicht funktionierendes Script: eine falsch formulierte Bedingung. Achten Sie darauf, dass Vergleichsoperatoren zwei Ist-Gleich-Zeichen haben und mehrere Bedingungen durch && oder || getrennt werden. Beispiel:
if(a = b)
while(0 == 0 & c == true)
Achten Sie darauf, dass alle Variablen initialisiert sind und zumindest als undefined bzw. NaN gelten. Beachten Sie auch den unterschiedlichen Geltungsbereich von lokalen Variablen, innerhalb einer Funktion, und globalen Variablen, die innerhalb des gesamten Scriptes verwendet werden. Schauen Sie evtl. nach doppelten Variablen-Namen um Überschreiben zu verhindern. Beispiel:
var a; function b(){return(a+10);}
var c,d; d += c;
Unterschiedliche Browser - unterschiedliches Verhalten. Nicht jeder Browser kennt jedes Objekt, nicht jeder Browser kann jedes Feature und kein Browser kann die Spezialitäten des anderen. Achten Sie also darauf evtl. Browserweichen einzubauen und das Script für verschiedene Browser fit zu machen. Beispiel:
document.all...
document.layers...
Nachdem keine Code-Fehler, wie die oben beschriebenen, mehr vorhanden sind geht es meist daran das Script zu testen, die 'inhaltlichen' Fehler zu finden und anschließend zu beseitigen. Diesen Teil nennt man allgemein debugging. Für diesen Vorgang gibt es einige Dinge, die Helfen Fehler im Ablauf zu entdecken oder allgemein das Script zu verbessern.
Ist der Fehler lokalisiert aber keine Lösung in Sicht diesen zu beheben, empfiehlt es sich unter Umständen erst einmal den Fehler aus zu schalten um den Rest des Scriptes weiter testen zu können. Dies kann z.B. durch ausklammern der betreffenden Stelle als Kommentar (/*... fehler ...*/) oder eine try-catch Anweisung geschehen. Beispiel:
//vorher:
function machFehler()
{x = 1; y += x; return(y);}
a = machFehler();
//nachher:
function machFehler()
{x = 1; /*y += x;*/ y = 1; return(y);}
a = machFehler();
//oder:
function machFehler()
{x = 1; try{y += x}catch(e){y = 1}; return(y);}
a = machFehler();
Meist tritt der Fehler nicht auf, weil etwas falsch notiert wurde, sondern weil einfach die Werte eines Objektes anders als geplant sind. Hierzu empfiehlt es sich, die Werte des betreffenden Objekts in regelmäßigen Abständen aus zu fragen. Folgendes Script ermittelt alle Werte eines Objektes (obj) und gibt diese aus:
function GetValues(obj)
{
var res = 'Objekt: '+obj+'\n\n';
for(temp in obj)
{
res += temp +': '+obj[temp]+'\n';
}
alert(res);
}
Beispiel:
//vorher:
if(document.meinobject.value == '13')
{alert('Alles in Ordnung!')}
else{alert('Irgendwas war falsch!')}
//nachher:
if(document.meinobject.value == '13')
{alert('Alles in Ordnung!')}
else
{
alert('Irgendwas war falsch!');
GetValues(document.meinobject);
}
Eine häufige Ursache von Browserabstürtzen sind Schleifen die nicht beendet werden, weil sie ihre Endbedingung nie erreichen. Hierbei empfiehlt es sich, neben dem Ausfragen, wie sich bestimmte Variablen innerhalb der Schleife verhalten, Möglichkeiten zum Beenden der Schleife zu schaffen, damit der Browser nicht jedes Mal beim Testen abstürzt. Beispiel:
//vorher:
a = 1; b = 2;
while(a != b){a+=2;}
//nachher:
a = 1; b = 2;
while(a != b)
{
a+=2;
if(confirm('Wert a = '+a+'. Weiter machen?') == false)
{break;}
}
Bei extrem langen Funktionen ist es unter Umständen besser (~ einfacher) die Möglichkeit zu haben, diese Vorzeitig beenden zu können. Eine einfache return-Anweisung verknüpft mit einer Bedingung reicht dafür völlig aus:
//vorher:
function abc(a)
{
a += 1;
//viele weitere Anweisungen
a -= 1;
}
//nachher:
function abc(a)
{
a = 1;
//viele weitere Anweisungen
if(confirm('Wert a = '+a+'. Weiter machen?') == false)
{return;}
//viele weitere Anweisungen
a -= 1;
}
In manchen Situationen steht nicht ganz fest, woran es denn nun liegt, dass das Script nicht macht was es soll. In diesem Fall ist es mitunter ratsam eventell Anweisungen wärend der Laufzeit des Scriptes einfügen zu können. Dazu braucht es nicht mehr als einer eval- und eine prompt-Anweisung. Beispiel:
//vorher:
a = 1; a++;
if(a == 3){machwas();}
//nachher:
a = 1; a++;
eval(prompt('Wert a = '+a'. Folgende Anweisung einschieben:'));
//Eingabe: "a = 3;"
if(a == 3){machwas();}
Eine wesentlich effizientere Variante des Debugging ist die Zuhilfenahme eines speziellen Programms, das dafür ausgelegt ist. Unter anderem bieten sich da der MS Script Debugger, der Netscape JavaScript Debugger und Mozillas Debugger "Venkman" an. Alle funktionieren in etwa ählich.
Nach der Installation des Microsoft Script Debuggers integriert sich dieser automatisch in den Internet Explorer. Tritt ein Fehler auf einer Seite auf, wird der Debugger automatisch gestartet. Innerhalb des Debuggers können Sie durch verschiedene Buttons den Ablauf des Scriptes nachverfolgen und kontrollieren. Als Werkzeuge bietet das Programm unter anderem eine Übersicht der aktuell geöffneten Dokumente, eine Übersicht des Funktions-Stack und ein Komanndo-Fenster. Bild:

Darstellung: Microsoft Script Debugger im Einsatz
Netscapes Debugger funktioniert ähnlich dem von Microsoft, allerdings mit dem Unterschied, dass es sich dabei um eine Java-Anwendung handelt, die erst über den Browser gestartet werden muss. Auch er bietet diverse Übersichten wie z.B. zu aktuellen Dokumenten und eine JavaScript Konsole. Außerdem besitzt das Programm einen 'Inspector' der es erlaubt die Werte von Variablen oder Eigenschaften zu verfolgen. Bild:

Darstellung: Netscape JavaScript Debugger im Einsatz
Mozillas Debugger ist normalerweise in den Mozilla schon mit integriert. Sollte das nicht der Fall sein, kann er (fast) problemlos nachinstalliert sein. Der Debugger wird im Hauptmenü unter 'Tasks/Tools/JavaScript Debugger' gestartet. Im Grunde ist er wie ein Mischung aus Microsofts und Netscapes Debugger. Er bietet ähnliche Übersichten, kommt allerdings bei Zusatztools ins Hinertreffen. Bild:

Darstellung: Mozilla Debugger: Venkman
Im Netz tummeln sich eine ganze Hand voll weiterer JavaScript Debugger. Einige sehr gute (aber meist nicht kostenlose) Exemplare die hier zu nennen wären sind z.B.