![]() |
|
|||||
switch (Ausdruck){ case Wert1: //Programmblock break case Wert2: //Programmblock break //usw. default: //Programmblock } Es dreht sich hierbei alles um Ausdruck, der in der Regel eine Variable ist. Hat dieser Ausdruck den Wert Wert1, wird der erste Programmblock ausgeführt, bei Wert2 der zweite Programmblock, und so weiter. Der default-Abschnitt wird ausgeführt, wenn keiner der vorherigen Werte zutrifft. Dieser Abschnitt ist optional. Jeder Programmblock muss mit dem Kommando break abgeschlossen werden. Das Monats-Beispiel lässt sich folgendermaßen umformulieren, und der Code ist deutlich kürzer und übersichtlicher: switch (monat){ case 1: var m = "Januar"; break case 2: var m = "Februar"; break case 3: var m = "März"; break case 4: var m = "April"; break case 5: var m = "Mai"; break case 6: var m = "Juni"; break case 7: var m = "Juli"; break case 8: var m = "August"; break case 9: var m = "September"; break case 10: var m = "Oktober"; break case 11: var m = "November"; break case 12: var m = "Dezember"; break default: var m = "Unbekannter Monat" } document.write(m) 4.2 Datenspeicherung
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Die Frage lautet nun: Wenn (beispielsweise in einer Variablen) die Monatsnummer vorliegt, wie erhält man dann daraus den Monatsnamen? Natürlich kann man eine Reihe von if-Anweisungen verwenden oder die switch-Anweisung, die jedoch nur ab der Browser-Version 4 (Netscape Navigator bzw. Internet Explorer) unterstützt wird. Schön wäre es jedoch, wenn man direkt den Variablennamen verwendet. Folgender Code funktioniert natürlich nicht wie beabsichtigt: |
document.write("Monat"+monat)
In monat steht die Monatsnummer, aber obige Zeile würde die Zeichenkette "Monat" konkateniert mit der Monatsnummer ausgeben, also den Namen der Variablen, nicht die Variable selbst. JavaScript bietet eine besondere Funktion, die es ermöglicht, Code auszuführen, der als Zeichenkette vorliegt. Diese Funktion heißt eval. Als Parameter wird eine Zeichenkette übergeben, und eval führt den JavaScript-Code aus, der in der Zeichenkette steht. Der folgende Aufruf gibt den Wert der Variablen zurück, nicht ihren Namen:
eval("Monat"+monat)
Will man also den Monatsnamen auf dem Bildschirm ausgeben, kann man folgende Zeile verwenden:
document.write(eval("Monat"+monat))
Alternativ dazu kann der document.write-Befehl auch innerhalb der eval-Klammern geschrieben werden:
eval("document.write(Monat"+monat+")")
Steht in der Variablen monat beispielsweise der Wert 12, so würde der eval-Befehl nach dem Einsetzen der Variablen folgendermaßen aussehen:
eval("document.write(Monat12)")
| Wenn in der Anweisung, die als Parameter an eval() übergeben wird, Anführungszeichen vorkommen, müssen Sie die herkömmlichen Regeln beachten, also entweder andere Anführungszeichen verwenden oder Anführungszeichen mit einem Backslash entwerten. Oft ist es jedoch sinnvoll, den Aufruf von eval() möglichst weit innen zu plazieren. |
document.write("Der Monatsname lautet "+eval("Monat"+monat))
Die obige Vorgehensweise funktioniert zwar tadellos, ist aber kompliziert, und auch hier werden die Befehle schnell unübersichtlich. In der Praxis werden zumeist sogenannte Arrays verwendet. Das sind Variablencontainer, die mehrere Variablen beinhalten können. Auf eine einzelne Variable im Container greift man über den Variablennamen und eine Nummer zu. Die Nummer nennt man auch Index. Standardmäßig wird ein Array in JavaScript folgendermaßen definiert:
var a = new Array() a[1] = "Januar" a[2] = "Februar" //usw.
Mit der ersten Zeile, var a = new Array(), wird eine Arrayvariable deklariert. Man kann auch einen Parameter übergeben, aber da gibt es je nach JavaScript-Version Unterschiede. Genauere Informationen finden Sie im Referenz-Teil. Kleiner Hinweis am Rande: Wenn man mehr als einen Parameter übergibt, kann man das Array vorbelegen:
var a = new Array("Januar", "Februar", "März")
Der Index, über den auf ein Array-Element zugegriffen wird, steht in eckigen Klammern. JavaScript-Arrays beginnen, wie in vielen anderen Programmiersprachen und in Java übrigens auch, mit 0. Mit obigem Aufruf würde also a[2] auf März gesetzt. Man müsste die Anweisung folgendermaßen modifizieren, damit a[3] den Wert »März« enthält:
var a = new Array("", "Januar", "Februar", "März")
| Leider werden Sie solchen Code nicht auf allen Seiten finden. Das hat historische Gründe: In allen Versionen des Netscape Navigator 2 waren Arrays nicht so. Der Internet Explorer 3 unterstützt auch nur eine Rohform der Arrays. Die Netscape-Entwickler haben das Problem erkannt (aber erst in Browser-Version 3 behoben) und in ihrer Dokumentation eine Möglichkeit vorgestellt, um Arrays auch mit dem Netscape Navigator 2 zu erzeugen. Eine leicht modifizierte Version dieses Codes wird hier vorgestellt. |
Zuerst einmal muss man auf allen Seiten, die Arrays verwenden, folgenden Code plazieren:
function MakeArray(n){ for (var i=0; i<n; i++) this[i] = 0 this.length = n }
Die exakte Funktionsweise dieses Codes wird teilweise später in diesem Kapitel, teilweise im Kapitel »Arrays« erläutert. Vereinfacht gesagt, kann nun mit MakeArray() ein Array erzeugt werden. Als Parameter wird die Anzahl der Elemente im Array festgelegt. Jedes Element wird mit dem Wert 0 vorbelegt. Außerdem kann man (bei korrekter Verwendung) über Arrayname.length herausfinden, wie viele Elemente das Array überhaupt enthält (wie bei »normalen« Arrays auch). Somit hat man die wichtigsten Funktionalitäten der JavaScript-Arrays nachgebildet.
| Das Beispiel von oben lässt sich nun folgendermaßen darstellen – und diesmal auch auf dem Netscape Navigator 2: |
var m = new MakeArray(13) m[0] = "Unbekannter Monat" m[1] = "Januar" m[2] = "Februar" m[3] = "März" m[4] = "April" m[5] = "Mai" m[6] = "Juni" m[7] = "Juli" m[8] = "August" m[9] = "September" m[10] = "Oktober" m[11] = "November" m[12] = "Dezember"
Beachten Sie, dass das Array 13 Elemente enthalten muss, da (zur besseren Übersichtlichkeit) der Index des entsprechenden Monatsnamens im Array mit der Monatszahl identisch sein soll. Es gibt also 13 Array-Elemente, der Index läuft von 0 bis 12.
Es stellt sich nun natürlich die Frage, ob man Netscape Navigator 2 (und indirekt auch Internet Explorer 3) überhaupt noch explizit unterstützen sollte, da der Anteil dieser Browserim niedrigen einstelligen Bereich liegt. Dennoch stehe ich auf dem Standpunkt, dass man – sofern möglich – abwärtskompatibel programmieren sollte. Auch wenn Benutzer alter Browser im Web sowieso eine Menge Fehlermeldungen gewohnt sind, hebt man sich gerade dann wohltuend von der Masse der Seiten (insbesondere der der Konkurrenten) ab, wenn man Fehlermeldungen möglichst vermeidet. Wenn der Aufwand nicht allzu groß ist (wie in diesem Fall), sollte man die Extra-Arbeit tun, denn ein potentieller Kunde könnte durch eine vermeidbare Fehlermeldung abgeschreckt werden (durch eine unvermeidbare sowieso).
In diesem Kapitel wird document.write() ziemlich oft eingesetzt. Es gibt jedoch zwei Nachteile dieser Funktion. Zum einen hat der Netscape Navigator 2 einen Bug, der dazu führt, dass ein document.write() innerhalb einer Tabellenzelle ohne Effekt ist (Ausnahme: Wenn die gesamte Tabelle mit document.write() erzeugt worden ist). Der zweite Nachteil ist ein (nicht auf document.write() beschränkter) Fehler im Netscape Navigator 3. Anweisungen der folgenden Art tauchen relativ oft auf:
document.write("<P>Winnie Pooh</P>")
Oft enthält die Zeichenkette noch weitaus mehr HTML-Tags. Der Netscape Navigator 3 kommt hierbei häufig durcheinander und gibt – trotz eigentlich korrektem Programmcode – eine Fehlermeldung aus. Abhilfe schaffen Sie hier, indem Sie nicht den gesamten Tag verwenden, sondern zumindest die spitzen Klammern als einzelne Zeichenketten behandeln und diese dann mit dem Plus-Operator konkatenieren:
document.write("<"+"P"+">"+"Winnie Pooh"+"<"+"/P"+">")
Bei vielen Anweisungen ist das recht aufwendig, vor allem die Tipparbeit verlangt viel Zeit und Konzentration. Hier kann man sich mit Funktionen behelfen. Unter einer Funktion versteht man einen Programmblock, der nicht sofort ausgeführt wird, aber explizit auf- bzw. abgerufen werden kann. So eine Funktion führt entweder ein paar Befehle aus (dann nennt man sie mitunter auch eine Prozedur), oder es wird ein Wert zurückgegeben. Eine Prozedur ist mit document.write() vergleichbar, während eine Funktion beispielsweise Zeichenkette.length entspricht.
Eine Funktion hat folgende Syntax:
function Funktionsname(Parameter1, Parameter2){ //Programmblock return Wert }
Die Anzahl der Parameter ist beliebig. Es kann auch kein Parameter verwendet werden (dann ist die Klammer leer). Innerhalb der Funktion können die Parameter dann unter dem Namen angesprochen werden, unter dem sie im Funktionskopf eingeführt wurden.
Die Zeile mit dem return ist optional. Der Befehl return sorgt dafür, dass die Funktion sofort verlassen wird (wie break). Wird hinter dem return ein Wert angegeben, so ist dieser der Rückgabewert der Funktion.
Im Gegensatz zu manchen anderen Programmiersprachen muss die Funktion nicht vor ihrem ersten Aufruf deklariert werden. Erkennt der JavaScript-Interpreter, dass ein Funktionsaufruf vorliegt, so wird das Dokument nach einer Funktion dieses Namens durchsucht.
Diese theoretische Einleitung soll anhand von praktischen Beispielen verdeutlicht werden. Prinzipiell geht es darum, dass an eine Funktion der Name eines Tags übergeben wird (beispielsweise "P" oder "FONT"), und die Funktion dann entweder den Tag ausgibt (mit den dazugehörigen spitzen Klammern) oder den Tag als Zeichenkette zurückgibt. Somit wird auch das obengenannte Problem mit den spitzen Klammern gelöst.
Die erste Variante gibt den entsprechenden Tag direkt mittels document.write() aus.
function tag_ausgeben(s){ document.write("<"+s+">") } //Test-Aufruf tag_ausgeben("P") document.write("Winnie Pooh") tag_ausgeben("/P")
In der zweiten Variante wird der return-Befehl verwendet. Die Funktion gibt also nichts direkt aus, sondern liefert einen Wert zurück, der dann im eigentlichen Programm weiterverwendet werden kann.
function tag(s){ return "<"+s+">" } document.write(tag("P")+"Winnie Pooh"+tag("/P"))
Es sind noch zwei Fälle möglich:
| Es werden weniger Parameter übergeben, als im Funktionsrumpf angegeben sind. |
| Es werden mehr Parameter übergeben, als im Funktionsrumpf angegeben sind. |
Der erste Fall lässt sich recht schnell abhandeln. In diesem Fall hat der entsprechende Parameter den Wert null. Die Funktion tag() kann also erweitert werden, so dass eine leere Zeichenkette zurückgegeben wird, wenn kein Parameter übergeben worden ist:
function tag(s){ if (s==null) return "" else return "<"+s+">" }
Der zweite Fall ist nicht ganz so einfach. Die gute Nachricht vorweg: Alle Parameter, die an eine Funktion übergeben werden, sind in einem Array gespeichert. Es ist jedoch noch nicht intuitiv einsichtig, wie auf dieses Array zugegriffen werden kann. Der entsprechende Bezeichner heißt Funktionsname.arguments – und hier sehen Sie gleich direkt, dass man als JavaScript-Funktionsnamen keine reservierten Begriffe (etwa document, write etc.) verwenden darf.
Die folgende Funktion gibt gleich eine ganze Liste von Tags aus. In einer for-Schleife wird das Array arguments durchlaufen, und alle Werte werden mit spitzen Klammern ausgegeben. Wie bereits oben angemerkt, kann mit Arrayname.length die Anzahl der Elemente des Arrays bestimmt werden; in obigem Fall also Funktionsname.arguments.length!
function tag(){ var returnstring = "" for (var i=0; i<tag.arguments.length; i++) returnstring += "<"+tag.arguments[i]+">" return returnstring }
tag("FONT SIZE='2'", "FONT FACE='Arial'", "B")
würde also folgende Zeichenkette als Ergebnis erhalten:
"<FONT SIZE='2'><FONT FACE='Arial'><B>"
Natürlich gibt es sinnvollere Einsatzgebiete für eine Funktion als Workarounds für Netscape-Bugs bereitzustellen. Kommen wir noch einmal zu Schleifen zurück. Es war ja immer etwas umständlich, ein Zeichen durch ein anderes auszutauschen. Mit einer Funktion kann man das ganze etwas übersichtlicher gestalten:
function ersetzeZeichen(Zeichenkette, Position, Neu){ //Zeichenkette ist die betrachtete Zeichenkette //Position ist die Pos. des Zeichens, das ersetzt wird //Neu ist das neue Zeichen var neueZ = Zeichenkette.substring(0, Position) neueZ += Neu neueZ += Zeichenkette.substring(Position+1, Zeichenkette.length) return neueZ }
Bei der Wahl der Variablennamen muss man Vorsicht walten lassen. Existiert die Variable auch außerhalb der Funktion, so wird keine neue Variable erzeugt, sondern auf die alte Variable zugegriffen. Umgekehrt kann man auf Variablen, die nur innerhalb einer Funktion auftreten, nicht von außen zugreifen. Man unterscheidet hier in globale (außerhalb und innerhalb einer Funktion gültig) und lokale (nur innerhalb von Funktionen gültig) Variablen. Will man innerhalb einer Funktion eine lokale Variable erzeugen, deren Name schon eine globale Variable trägt, so muss man der ersten Verwendung ein var voranstellen.
Folgendes Beispiel verdeutlich das eben Gesagte:
var a=0 var b=0 function test(){ a++ //Zugriff auf globale Variable a var b=1 //Neue lokale Variable //hat mit der globalen Variablen b nichts zu tun var c=0 //Neue lokale Variable }
JavaScript gehört zu den sogenannten objektorientierten Programmiersprachen (oder, um genauer zu sein, zu den objektbasierten Sprachen). Das Konzept der objektorientierten Programmierung (OOP) wird im folgenden sehr stark vereinfacht erklärt. Der interessierte oder vorgebildete Leser möge diese Vereinfachung verzeihen, aber für das Verständnis von JavaScript ist nur ein gewisser Überblick über das Konzept der Objektorientierung in JavaScript nötig.
In JavaScript ist (mit Ausnahme der Variablen) alles, worauf man zugreift, ein Objekt. Ein Objekt ist der Versuch, die reale Welt in eine Programmiersprachenumgebung abzubilden. Ein Standardbeispiel für Objekte ist etwa ein Auto. Das Auto an sich (als abstrakter Begriff) kann als Objekt angesehen werden, ein einzelnes Auto wird als Instanz des Objekts //Auto// bezeichnet. Sie haben so etwas in diesem Kapitel schon einmal gesehen – Array ist so ein Objekt, und mit new Array() wird eine Instanz des Array-Objekts, also ein konkretes Array erzeugt.
Ein Auto, oder ein Objekt im allgemeinen, wird durch gewisse Parameter spezifiziert. Bei diesen unterscheidet man Methoden und Eigenschaften.
| Eine Eigenschaft kann als Variable angesehen werden, also als ein Wert, der fest mit dem Objekt verbunden ist und gelesen und geschrieben (gesetzt) werden kann. Bei einem Auto ist das beispielsweise die aktuelle Geschwindigkeit oder die aktuelle Menge Benzin im Tank. Eine Eigenschaft kann mit einem Funktionsaufruf verglichen werden, der immer einen Wert zurückgibt. |
| Eine Methode ist eine Funktion, die ebenfalls fest mit dem Objekt verbunden ist. Im Gegensatz zur Eigenschaft wird hier aber nicht immer ein Wert zurückgegeben. Um auf das Auto-Beispiel zurückzukommen: Eine mögliche Methode wäre eine Methode vollbremsung(), die die (Eigenschaft) Geschwindigkeit abrupt auf 0 setzt. Eine andere Möglichkeit wäre eine Methode beschleunigen(); je nach Definition könnte man als Parameter angeben, auf welche Geschwindigkeit oder um wieviel Stundenkilometer die Geschwindigkeit erhöht werden soll. An der Schreibweise sieht man schon eine verwendete Konvention: Methoden werden immer durch nachgestellte Klammern gekennzeichnet; dies soll verdeutlichen, dass es sich hier nicht um eine Eigenschaft, sondern um einen »echten« Funktionsaufruf handelt. |
Wie Sie vielleicht schon bei den vorherigen Beispielen in diesem Kapitel gesehen haben, ruft man eine Eigenschaft oder eine Methode auf, indem man den Namen des entsprechenden Objekts nimmt und den Namen der Methode oder Eigenschaft mit einem Punkt anhängt. Methoden werden dabei immer mit Klammern geschrieben; sollten keine Parameter übergeben werden, so werden leere Klammern verwendet. Bei Eigenschaften werden keine Parameter übergeben. Um auf die vorherigen Beispiele zurückzukommen: document.write() ist eine Methode des document-Objekts, Arrayname.length ist eine Eigenschaft des Array-Objekts.
In den folgenden Kapiteln werden Sie nach und nach alle JavaScript-Objekte kennenlernen. Einige davon, wie beispielsweise das Array-Objekt, erleichtern die Programmierung, haben aber mit Webseiten nichts zu tun. Man kann von diesen Objekten Instanzen erzeugen und diese dann verwenden. Andere Objekte wiederum, wie beispielsweise die Objekte window, document oder location, haben dagegen direkt etwas mit der entsprechenden Webseite zu tun und enthalten beispielsweise Informationen über die URL der aktuellen Seite oder die Anzahl der Links im HTML-Dokument. In den nächsten Kapitel werden diese Objekte an praxisnahen Beispiele vorgeführt.
Wenn Sie eigene Objekte erstellen möchten, sollten Sie das Kapitel »Arrays« lesen, dort wird dies an einem Beispiel durchexerziert. Im Praxiseinsatz werden Sie – vor allem bei »Standardaufgaben« – eher selten selbst Objekte erstellen, aber bei größeren Projekten ist das mitunter sehr nützlich.
| 1. | Schreiben Sie das Beispiel mit den Monatsnamen derart um, dass nicht der Name des aktuellen Monats ausgegeben wird, sondern der des Folgemonats. |
| 2. | Wie Aufgabe 1, nur verwenden Sie weder Arrays noch if-Abfragen. |
| 3. | Schreiben Sie eine Funktion istSchaltjahr(n), die angibt, ob n ein Schaltjahr ist oder nicht (Tip: Modulo-Operator verwenden!). Zusatzaufgabe: Versuchen Sie auch hier, ohne if-Abfragen auszukommen. |
| 4. | Schreiben Sie eine Funktion istPrim(n), die angibt, ob n eine Primzahl2 ist. |
| 5. | Ist die Funktion zum Ausgeben von modalen Hinweisfenstern (Warnfenstern), die Sie im Kapitel »Vorbereitung« kennengelernt haben, eine Methode, eine Eigenschaft oder keins von beiden? Geben Sie eine Begründung an! |
| 6. | Versuchen Sie, die Funktion MakeArray() so umzuschreiben, dass ein optionaler zweiter Parameter unterstützt wird, der den Initialwert für jedes Arrayfeld angibt. Sie müssen dazu unter anderem die Zeile ändern, in der allen Array-Elementen der Wert 0 zugewiesen wird. |
1 Das ist gleichzeitig auch ein Nachteil – bei obigem Code werden für jeden Wert von monat 12 Überprüfungen durchgeführt.
2 Eine Primzahl ist nur durch zwei verschiedene Zahlen ohne Rest teilbar: durch eins und sich selbst. Daraus folgt, dass eins selbst keine Primzahl ist.
| << zurück |
| |||||
| |||||
| |||||
| |||||
| |||||
| |||||
| |||||
| |||||
Copyright © Galileo Press GmbH 2001 - 2002
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken und speichern. Ansonsten unterliegt das <openbook> denselben Bestimmungen wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.
Die Veröffentlichung der Inhalte oder Teilen davon bedarf der ausdrücklichen schriftlichen Genehmigung von Galileo Press. Falls Sie Interesse daran haben sollten, die Inhalte auf Ihrer Website oder einer CD anzubieten, melden Sie sich bitte bei: stefan.krumbiegel@galileo-press.de