Teil von SELFHTML aktuell Teil von Artikel Teil von JavaScript

HelferleinScript 'Debug-Infos':
Variablen auf Existenz prüfen und deren Werte ausgeben

nach unten Horst Nogajski
nach unten Hinweise zum Thema
nach unten Beispiel und Erläuterungen
nach unten Weiterführende Links

Horst Nogajski

E-Mail: E-Mail h.nogajski@web.de
Homepage-URL: deutschsprachige Seite http://www.nogajski.de/

Bei Fragen zu diesem Beitrag bitte den Autor des Beitrags kontaktieren!

nach obennach unten

Hinweise zum Thema

Man schreibt eine Seite, in der man auch tüchtigerweise eine ansehnliche Menge JavaScript-Code einsetzt. Leider reagiert das Script an manchen Stellen oder in bestimmten Browsern nicht so, wie man es geplant hat.
Unter Umständen hilft es schon, sich an bestimmten Stellen im Quellcode den Wert einer Variablen anzeigen zu lassen, um dem Fehler auf die Spur zu kommen. Also schreibt man schnell hier und dort ein alert() hin und gibt mit diesem dann den Wert einer Variablen aus.

Wenn es aber mehrere unterschiedliche Variablen an verschiedenen Stellen sein sollen? Da kann es schnell zu sehr unübersichtlichen Konstrukten kommen. Deshalb ist es vorteilhaft, ein Script zu haben, das man an zentraler Stelle speichern und pflegen kann (z.B. http://localhost/debuginfos.js). Damit ist es möglich, mehrere Gruppen von Variablen, auch unterschiedlicher Projekte, für solche alert() Abfragen anzulegen, ohne unnötig viel in die original Projektdateien schreiben zu müssen.

Programmiertechnische Grundlagen

Um eine Vielzahl von Variablen problemlos handhaben zu können, ist es unbedingt notwendig, zunächst die Existenz der Variable zu prüfen.
Dazu kann man sich des Operators zur Typenbestimmung typeof bedienen. Eine weitere Möglichkeit ist, dies mit dem try..catch - Statement zu prüfen. Da letzteres aber erst mit Browsern, die mindestens JavaScript 1.5 verstehen möglich ist und der typeof Operator schon in JavaScript 1.1 bekannt ist, wird diesem hier der Vorrang gegeben. Bei den weiteren nötigen/möglichen Befehlen und Funktionen (array.delete, array.push, array.pop) wurden auch solche gewählt, die eine größtmögliche Rückwärtskompatibilität erlauben. So kann das Script ab NS4 und IE4 bzw. mit Browsern, die JavaScript 1.2 verstehen, genutzt werden.

nach obennach unten

Beispiel und Erläuterungen

Beispiel:

Popup-Seite Anzeigebeispiel: So sieht's aus

<!-- Beispiel HTML Datei -->

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Beispieldatei: DebugInfos</title>

   <!-- nur während der Entwicklungsphase eingebundene, zentrale JS-Datei -->
   <script language="JavaScript1.2" src="debuginfos.js" type="text/JavaScript"></script>

<script language="JavaScript1.2" src="objekte.js" type="text/JavaScript"></script>
<script language="JavaScript1.2" type="text/JavaScript">
<!--

 DI(1,'Aufruf vor Initialisierung der Variablen'); // Ausgabe von Informationen zu Variablen und Werten anfordern

    // Objektinstanzen und Variablen initiieren
    var loaded=false;                             // BeispielVariable (boolean)
    var NumberOne = 22;                           // BeispielVariable (number)
    var StringVar1 = "globale TextVariable eins"; // BeispielVariable (string)
    var StringVar2 = "globale TextVariable zwei"; // BeispielVariable (string)
    var Win;                                      // Beispiel-Objekt  (Window-Werte)

 DI(1,'Aufruf nach der Initialisierung'); // Ausgabe von Informationen zu Variablen und Werten anfordern

    // wird beim Ereignis 'resize' aufgerufen
    function checkSize() {
 DIC(); // Counter-Aufruf (= Wert um 1 erhoehen)
       Win = new lib_win();      // aktuelle Fensterwerte in die Objektinstanz lesen
    }

    // wird beim Ereignis 'onload' aufgerufen
    function setloaded() {
     var StringVar2 = "lokale Stringvariable 2";
         loaded = true;
         NumberOne += 12;
         Win = new lib_win();
         StringVar1 = "Neuer Text in globale TextVariable eins";
         StringVar2 = "Neuer Text in lokale Stringvariable zwei";

                   // Beachten Sie, dass hier die _lokale_ Variable 'StringVar2'
                   // gleichnamig ist mit der _globalen_ Variablen 'StringVar2'!
                   // In den DebugInfos ueberprueft und angezeigt wird aber
                   // nur der Wert der _globalen_ Variable!

 DI(1,'Aufruf innerhalb der onLoad-Funktion'); // Ausgabe von Informationen zu Variablen und Werten anfordern

    }

//-->
</script>
</head>

<body onload="setloaded()" onResize="checkSize()">
<p>
<br><br>
<a href="javascript:DI(1,'Abfrage der Wertegruppe 1')">Abfrage Wertegruppe 1</a>
<br><br>
<a href="javascript:DI(2,'Abfrage der Wertegruppe 2')">Abfrage Wertegruppe 2</a>
<br><br>
<a href="javascript:DI('','')">Nur Counter Abfrage</a>
<br><br>
</p>
</body>
</html>


<!-- die externe Scriptdatei: debuginfos.js -->


var counter = 0;

// Gruppen mit abzufragenden Variablen definieren (und bei Bedarf Trennlinien)
//
// WICHTIG! Wenn Sie Werte von Objektinstanzen abfragen wollen (z.B.: Win.IW),
// duerfen Sie mit if-typeof nur das Vorhandensein der Objektinstanz selber ueberpruefen.
// RICHTIG: if(typeof Win == 'undefined') ...
// FALSCH:  if(typeof Win.IW == 'undefined') ...
// Anderenfalls erzeugen Sie bei Nichtvorhandensein der Objektinstanz einen Error.
//
function GetMyArrayNumber(N) {

 out = new Array();           // out als _globales_ Array anlegen!
 var VarName, VarValue;

 if(N==1) {

     VarName = "Win.IW";
     if (typeof Win == 'undefined') VarValue = "undefined"; else VarValue = Win.IW;
     push(VarName,VarValue);

     VarName = "Win.OW";
     if (typeof Win == 'undefined') VarValue = "undefined"; else VarValue = Win.OW;
     push(VarName,VarValue);

     push("-",0);

     VarName = "Win.IH";
     if (typeof Win == 'undefined') VarValue = "undefined"; else  VarValue = Win.IH;
     push(VarName,VarValue);

     VarName = "Win.OH";
     if (typeof Win == 'undefined') VarValue = "undefined"; else VarValue = Win.OH;
     push(VarName,VarValue);

     push("-",0);

     VarName = "Variable1";
     if (typeof Variable1 == 'undefined') VarValue = "undefined"; else VarValue = Variable1;
     push(VarName,VarValue);

     VarName = "Variable2";
     if (typeof Variable2 == 'undefined') VarValue = "undefined"; else VarValue = Variable2;
     push(VarName,VarValue);

     VarName = "loaded";
     if (typeof loaded == 'undefined') VarValue = "undefined"; else VarValue = loaded;
     push(VarName,VarValue);


  } else if(N==2) {

     VarName = "bw.agent";
     if (typeof bw.agent == 'undefined') VarValue = "undefined"; else VarValue = bw.agent;
     push(VarName,VarValue);

     VarName = "bw.dom";
     if (typeof bw.dom == 'undefined') VarValue = "undefined"; else VarValue = bw.dom;
     push(VarName,VarValue);

  } else if(N=='Projekt1 Gruppe3') {

     // Definition der 3. Gruppe von Variablen, die Sie in Ihrem Projekt hin und wieder aufrufen moechten ;-)

  } else {

     alert('DebugInfos abfragen ist nicht moeglich. Es fehlen Angaben!');

  }
}


// Schluessel und Werte in das globale Array 'out' schreiben
//
function push(key,value) {
   var i = out.length;
   out[i] = new Array();
   out[i]['key']=key;
   out[i]['value']=value;
}


// Aufruf erhoeht den Counter um 1
//
function DIC() {++counter;}


// Gibt die Infos der gewuenschten Variablen-Gruppe aus
//
// Wenn weder fuer N noch msg Parameter uebergeben wurden ( also: DI('','') )
// wird nur der aktuelle Stand des counters angezeigt.
// Anderenfalls ist mindestens fuer N die gewuenschte Gruppe der anzuzeigenden Variablen,
// wie sie in der Funktion GetMyArrayNumber(N) definiert sind, anzugeben.
// Fuer msg ist eine Zeichenfolge (oder leere Zeichenfolge '') anzugeben.
//
function DI(N,msg) {

 var ZU = "\n"; // Zeilenumbruch im AlertWindow (funktioniert so auch unter Windows. Anderenfalls: \r\n)

 var info  = "------- [Debug Infos] --------------------------------("+counter+")---"+ZU+ZU;

 if(N=="" && msg=="") {
     msg = "(Nur Counterinfo)";
     info += msg + ZU;
     info += ZU+"---------------------------------------------------------------"+ZU;

 } else {

     GetMyArrayNumber(N);   // fuellt das Array 'out' mit den Schluesseln und Werten der Gruppe 'N'

     info += msg + ZU;
     info += ZU+"---------------------------------------------------------------"+ZU;
     for (var i=0; i < out.length; ++i) {   // schreibt alle Schluessel-Wert-Paare aus 'out' in die Variable Info
       if(out[i]['key']=='-') {
         info += "---"+ZU;
       } else {
         info += out[i]['key'] + " = " + out[i]['value'] + ZU;
       }
     }
     info += "---------------------------------------------------------------"+ZU;

  }

     alert(info);     // gibt alle Informationen aus
     delete out;      // globales Array 'out' wird geloescht!
}

Erläuterung:

In die HTML-Datei wird während der Entwicklungsphase die externe JavaScript-Datei debuginfos.js eingebunden. In dieser Datei definiert man in der Funktion GetMyArrayNumber(N) einen Block (oder mehrere Blöcke) mit Variablen, deren Werte oder Existenz man überprüfen möchte. An die Variable VarName wird per string (Zeichenfolge) der Name der zu überprüfenden Variable übergeben.

In der Zeile darunter übergibt man einmal den Wert der Variable an den 'Operator zur Typenbestimmung' typeof. Zur Laufzeit wird so überprüft, ob die Variable vom Typ 'undefined' ist. Das wäre sie, wenn sie a) gar nicht existent ist, oder b) keinen gültigen Wert enthält. Für unser Vorhaben muss als gültiger Wert einer der folgenden Typen zurückgegeben werden: string, number, boolean oder (mit Einschränkung) object. Wenn der Testkandidat bei der Überprüfung ein true (richtig/wahr) zurückgibt, wird für die lokale Variable VarValue die Zeichenfolge 'undefined' als Wert übergeben (VarValue = "undefined";). Wenn die Überprüfung ein false (falsch/unwahr) zurückgibt, wird der lokalen Variable VarValue der tatsächliche Wert des Testkandidaten übergeben (VarValue = originalValue;). Anschließend schreibt die Funktion push(Varname,VarValue) die Werte als neue Schlüssel-Werte-Paare in das globale Array 'out'.

Sie müssen also einmal den Namen und zweimal den Wert des Testkandidaten in diese Routine schreiben. Peinlich korrekte Syntaxprüfung aller drei Variabelennennungen an dieser Stelle kann später einige Kopfschmerzen ersparen.

Für jeden weiteren 'Testkandidaten' wiederholt man das. Um eine bessere Übersicht bei der Ausgabe mehrerer Variablen zu erreichen, kann man Trennzeilen einfügen. (push("-",0);)

Die Funktion push(key,value) ermittelt mit out.length die Anzahl der momentan im Array befindlichen Einträge. Wenn z.B. 10 Einträge vorhanden sind, liefert array.length den Wert 10 zurück. Der 10. Eintrag eines Arrays hat die Positionsnummer 9, da der erste Eintrag die Positionsnummer 0 hat (und nicht 1), deshalb wird mit dem ermittelten Wert ein neuer (der 11.) Eintrag an Positionsnummer 10 erstellt. Diesem Eintrag werden dann der Name und der aktuelle Wert der zu überprüfenden Variable zugewiesen.

Die Zuweisung eines neuen Wertes an letzter Stelle eines Arrays, also ein einfaches Anhängen, lässt sich etwas bequemer mit array.push vornehmen. Doch dieser Befehl steht, obwohl JavaScript 1.2, erst ab IE 5.5 zur Verfügung und wird deshalb hier nicht genutzt. Das Pendant dazu ist array.pop.

Durch einen Aufruf der Funktion DI(N,msg) in der HTML-Datei erreicht man an dieser Stelle des Scripts die Ausgabe von Informationen zu den Variablen des mit N selektierten Blocks in der Funktion GetMyArrayNumber(N). Mit msg kann man der Ausgabe einen kurzen Hinweis beifügen, der bei mehreren Ausgaben in einem Durchlauf zu mehr Übersicht verhilft. Wenn weder für N noch für msg ein Parameter übergeben werden, also DI('',''), wird nur der aktuelle Stand eines Counters angezeigt. Mit Hilfe des Counters kann man z.B. die Anzahl ausgelöster Impulse für einen Eventhandler zählen. In der Beispieldatei ist der Zähler in der Funktion checksize(), die onResize aufgerufen wird, gesetzt. (Verkleinern und vergrößern Sie doch mehrmals das Fenster und schauen sich danach eine Ausgabe an.)

In der Beispieldatei werden einige Variablen unterschiedlichen Typs und eine Objekt-Instanz definiert. Die Objektinstanz gibt Werte zu Breite und Höhe Ihres Browserfensters wieder, sofern Sie einen der folgenden Browser benutzen: IE, Mozilla und Derivate (Netscape, K-Meleon, Galeon, etc) und Opera. Während des Ladevorgangs werden an drei Stellen Informationen der Gruppe eins ausgegeben. Ein Zähler ist per Funktion an das Resize-Ereignis gebunden. Weiterhin wird bei der Auslösung des Resize-Ereignisses immer die Instanz des Fensterobjektes aktualisiert. Als Möglichkeit, nach dem Laden der Beispieldatei auch die aktuellen Werte abfragen zu können, gibt es drei Links mit denen Sie jeweils die Funktion DI(N,msg) mit unterschiedlichen Parametern aufrufen können. Und mit der Reload-Taste Ihres Browsers können Sie die Ausführung ja wiederholen.

Wenn Sie Werte von Objektinstanzen abfragen wollen (z.B.: Win.IW), sollten Sie mit if-typeof nur das Vorhandensein der Objektinstanz selbst überprüfen, andernfalls erzeugen Sie bei Nichtvorhandensein der Objektinstanz einen unbehandelten Error und das Script bricht ab.

Beispiel:
Sichere Abfrage des Wertes für Win.IW: if(typeof Win == 'undefined') ...
Unsichere und evtl. zu einem Error führende Variante: if(typeof Win.IW == 'undefined') ...

nach obennach unten

Weiterführende Links

Die folgenden Stellen werden empfohlen, um das obige Beispiel besser zu verstehen, oder um weitere Möglichkeiten und Details zu erfahren.

bereichsübergreifende Seite SELFHTML: Operator zur Typenbestimmung
bereichsübergreifende Seite SELFHTML: Fehlerbehandlung mit dem try..catch - Statement
bereichsübergreifende Seite SELFHTML: Variablen definieren
bereichsübergreifende Seite SELFHTML: Eigene Objekte definieren
bereichsübergreifende Seite SELFHTML: assoziative Arrays

Teil von SELFHTML aktuell Teil von Artikel Teil von JavaScript

© 2007 bereichsübergreifende Seite Impressum