|
FAQ de.comp.lang.javascript |
|
|||||||||||
Bitte verwenden Sie als Einstiegsadresse in diese FAQ die
Homepage der Newsgroup de.comp.lang.javascript.
Der Aufenthaltsort dieser Seiten hier kann sich ohne Vorwarnung ändern.
Möchte man auf eine Eigenschaft oder Methode eines Objekts zugreifen und dieses Objekt ist wider Erwarten nicht vorhanden, erzeugt man damit einen Skriptfehler. Die weitere Ausführung des Skripts wird dann abgebrochen und dem Benutzer wird mitunter eine unschöne Fehlermeldung präsentiert, wie "foo has no properties", "bar ist null oder kein Objekt", "baz is not convertible to Object" oder ähnlich.
Um dies zu vermeiden, prüft man sinnvollerweise auf die Existenz jedes Objekts, von dessen Existenz man nicht ganz sicher ausgehen kann, bevor man einen Zugriff auf seine Eigenschaften oder Methoden versucht. In diesem Artikel wird beschrieben, wie man das programmiertechnisch sinnvoll und einigermaßen kompakt lösen kann.
Nehmen wir als Beispiel eine Anweisung, wie sie in Dynamischem HTML recht häufig
vorkommt. Die Hintergrundfarbe (backgroundColor) eines HTML-Elements soll
damit auf schwarz ("#000000") gesetzt werden:
document.getElementById("foo").style.backgroundColor = "#000000";
Hier finden wir gleich drei Zugriffe auf Eigenschaften oder Methoden von Objekten, deren Existenz wir nicht als sicher voraussetzen dürfen:
getElementById() des document-Objekts ist in älteren, nicht
zum W3C-DOM kompatiblen, Browsern nicht verfügbar.
foo ist vielleicht nicht verfügbar, dann
besäße der Rückgabewert von getElementById() (dieser
wäre dann null) keinerlei Eigenschaften.
getElementById() zwar
ein von null verschiedenes Objekt zurückgäbe, dieses jedoch aus irgendwelchen
Gründen gar keine Eigenschaft style besäße.
Um Fehler auszuschließen, müssen wir also auf die Existenz dieser drei Objekte
testen. Hierbei machen wir uns zunutze, dass JavaScript es uns erlaubt, einfach das zu
prüfenden Objekt als Ausdruck in einer if-Anweisung zu verwenden, um grob
zu prüfen, ob der Ausdruck denn das gewünschte Objekt tatsächlich
referenziert oder nicht
1):
if (document.getElementById) {
if (document.getElementById("foo")) {
if (document.getElementById("foo").style) {
document.getElementById("foo").style.backgroundColor = "#000000";
}
}
}
Dabei muss nun der Interpreter gleich dreimal denselben Ausdruck
document.getElementById("foo") auswerten. Um dies zu ersparen, weisen
wir den dazugehörigen Wert einer Hilfsvariablen oElement zu:
var oElement;
if (document.getElementById) {
oElement = document.getElementById("foo");
if (oElement) {
if (oElement.style) {
oElement.style.backgroundColor = "#000000";
}
}
}
Dieselbe Vereinfachung
2)
nehmen wir nun für das zweimal vorkommende oElement.style vor, als
Hilfsvariable dient hier oStyle:
var oElement, oStyle;
if (document.getElementById) {
oElement = document.getElementById("foo");
if (oElement) {
oStyle = oElement.style;
if (oStyle) {
oStyle.backgroundColor = "#000000";
}
}
}
Um dies nun weiter zu vereinfachen, machen wir uns zunutze, dass in JavaScript der Wert einer
Wertzuweisung (mit dem Operator "=") gleich dem zugewiesenen Wert ist.
Wir können daher die beiden Zuweisungen zu den Hilfsvariablen einfach als Ausdruck der
if-Anweisungen notieren
3):
var oElement, oStyle;
if (document.getElementById) {
if ((oElement = document.getElementById("foo"))) {
if ((oStyle = oElement.style)) {
oStyle.backgroundColor = "#000000";
}
}
}
Wollen wir jeden der drei Umstände "document.getElementById nicht
vorhanden", "Element mit der ID foo nicht vorhanden" und
"Eigenschaft style nicht vorhanden" gesondert behandeln, fügen wir
an jede der drei if-Anweisungen noch einen else-Zweig mit der
entsprechenden Fehlerbehandlung an. Ansonsten verwenden wir zuletzt zur weiteren
Vereinfachung noch den logischen UND-Operator "&&", um die
drei if-Anweisungen zu einer einzigen zusammenzufassen
4):
var oElement, oStyle;
if (document.getElementById
&& (oElement = document.getElementById("foo"))
&& (oStyle = oElement.style)) {
oStyle.backgroundColor = "#000000";
}
Das ist nun zwar immer noch deutlich länger als der ursprüngliche Einzeiler, jedoch stellt es eine kurze und kompakte Möglichkeit ohne überflüssige mehrfache Referenzierungen dar, die oben beschriebene Fehlerquelle zu umgehen. Ein weiteres Beispiel: Aus dem fehlerträchtigen
document.forms["foo"].elements["bar"].value = 42;
wird auf gleiche Weise das sichere
var myForm, myElement;
if (document.forms
&& (myForm = document.forms["foo"])
&& (myElement = myForm.elements["bar"])) {
myElement.value = 42;
}
Auch, wenn das zunächst etwas kompliziert aussieht: wenn man das erst ein paarmal so notiert hat, geht es sehr leicht von der Hand, da das Vorgehen ganz grundsätzlich immer dasselbe ist.
null,
undefined, 0 oder false referenziert, denn als
Ausdruck in einer if-Anweisung (also in einem booleschen Kontext) werden in
JavaScript aufgrund dessen "lockerer" Typisierung die vier genannten Werte als
boolescher Wert false, alle anderen Werte hingegen als boolescher Wert
true interpretiert.
↑document.getElementById kann man diese
Vereinfachung in manchen Browsern leider nicht vornehmen, weshalb wir dies so belassen
müssen.
↑=" mit dem in if-Anweisungen sehr viel häufiger
benötigten Vergleichsoperator "==" meldeten. Statt:
if (a=b) ... müssen wir notieren: if ((a=b))....
↑a einen der Werte false,
null, 0 oder undefined liefert, wird b
in einem Ausdruck a && b gar nicht mehr ausgewertet.
↑Diese Seite ist Teil der de.comp.lang.javascript FAQ. Die Einstiegsadresse lautet http://www.dcljs.de/.
Dieser Text wurde erstellt von Dietmar Meier (©).
© S. Mintert, Ch. Kühnel
______ letzte Änderung: 22.06.2005 ______