JavaScript – M+T Pocket . Das Programmier-Handbuch (Office Einzeltitel) [Taschenbuch]

6.7
Anweisungen und Kontrollfluss-Steuerung

Von elementarer Bedeutung in der Programmierung sind
Anweisungen, d.h. sprachspezifische Befehle bzw. Befehlsfolgen. Insbesondere
solche, die zur Steuerung des Programmflusses eingesetzt werden.

6.7.1
Allgemeine Anweisungen

Anweisungen werden in einem JavaScript der Reihe nach oder
aufgrund einer bestimmten Konstellation ausgeführt. Dabei kann man verschiedene
Arten von Anweisungen unterscheiden.

Blockanweisungen

In JavaScript werden größere Quellcodeabschnitte zu
Blockstrukturen mit geschweiften Klammern { … } zusammengefasst, die dann einen
Block bzw. eine Blockanweisung . Dies haben wir in fast allen Beispielen
bereits angewandt.

Deklarationsanweisungen

Deklarationsanweisungen bedeuten die Einführung eines neuen Elements im Script. Etwa eine Variable oder
eine Funktion.

Ausdrucksanweisungen

Ausdrucksanweisungen bedeuten einmal die Wertveränderung als
Ergebnis der Verbindung von Operanden und Operatoren über die syntaktischen
Regeln einer Scriptsprache. Dies ist die so genannte Zuweisungsanweisung, die
rechts von einem Zuweisungsoperator einen Wert (konstant oder berechnet) stehen
haben, der dem linken Ausdruck zugewiesen wird. Alle Ausdrucksanweisungen
müssen in JavaScript mit einem Semikolon beendet werden und werden immer
vollständig durchgeführt, bevor die nächste Anweisung ausgeführt wird.

Die zweite Variante sind Auswahlanweisungen, die in einem
Script unter gewissen Situationen einen von mehreren möglichen Kontrollflüssen
aussuchen. Sie dienen der Ablaufsteuerung von einem Script. Davon gibt es
diverse Varianten.

6.7.2
Kontrollflussanweisungen

Kontrollflussanweisungen sind eine Angabe, unter welchen Voraussetzungen und wie oft nachfolgend notierte
Anweisungen ausgeführt werden. Sie dienen also explizit der Ablaufsteuerung in
einem Script. Man unterscheidet die nachfolgenden Kategorien.

Sprunganweisungen

Sprunganweisungen geben die Ablaufsteuerung eines Scripts an eine aufrufende Stelle zurück. Sie dienen der Ablaufsteuerung von Scripten.
JavaScript kennt die Anweisung

return

zur Rückgabe eines Wertes und Rückgabe des Kontrollflusses (für Beispiele siehe Seite 93), sowie die Anweisung

break,

um ohne Rückgabewert den Programmfluss zurückzugeben. Seit JavaScript 1.2 kann bei der break-Anweisung
die Angabe eines Labels, d.h. einer Sprungadresse, erfolgen. Diese gibt an, wo
nach Ausführen der break-Anweisung
mit der Abarbeitung des Codes fortgefahren werden soll. Das Label ist ein frei
definierbarer Name an einer beliebigen Stelle im Quelltext, der mit einem
nachgestellten Doppelpunkt notiert wird. Hinter dem Wort break können Sie dann durch Leerzeichen
abgetrennt den Namen des Labels angeben.

Sprungadressen werden von vielen Browser nicht
unterstützt.

Als dritte Anweisung gibt es

continue,

womit in einer Schleife unmittelbar der nächste Schleifendurchlauf erzwungen werden kann. Die nachfolgenden Anweisungen innerhalb der
Schleife werden ignorieren.

Wir werden die Sprunganweisungen gleich im Rahmen der
Behandlung von Entscheidungsanweisungen einsetzen und an Hand praktischer
Beispiele erläutern.

Auswahl- und Iterationsanweisungen

JavaScript kennt die in den meisten Sprachen üblichen
Auswahl- und Iterationsanweisungen. Da gibt es beispielsweise die if-Auswahlanweisung.

Die if-Anweisung

Die if-Auswahlanweisung
überprüft, ob eine Bedingung erfüllt ist. Wenn ja, werden die nachfolgend
notierten Anweisungen ausgeführt. Grundsätzliche Syntax ist immer die folgende:

if ([Bedingung]){

…Anweisungen

}

Unter Bedingung
versteht man einen Vergleich, ein Boolesches Literal bzw. eine Boolesche
Variable oder den Rückgabewert einer Funktion, der entweder wahr (true) oder falsch
(false) sein
kann. Eine Bedingung kann aus mehreren Bestandteilen bestehen, die über die
logischen Operatoren
&& für eine Und-Verknüpfung und || für eine Oder-Verknüpfung verknüpft
werden. Diese können obendrein beide gleichzeitig verwendet werden und auch die
Anzahl der Bedingungen ist im Prinzip unbeschränkt. Es ist eigentlich nur ein
logisches Problem, eine gewisse Anzahl von verknüpften Bedingungen auch so zu
formulieren, dass sie den gewünschten Sinn repräsentieren.

<HTML>

<HEAD>

<SCRIPT
language="JavaScript">

var pw = prompt("Bitte geben Sie Ihr Passwort
ein","");

if(pw=="geheim") {

document.write(

"<H1 align=center>Herzlich Willkommen auf
meiner Homepage</H1><br>");

}

</SCRIPT>

</HEAD>

<BODY></BODY>

</HTML>

Listing 6.16: Der Einsatz von if in
Entscheidungsstrukturen

Beim Laden der Webseite werden Sie aufgefordert, ein Paßwort
einzugeben. Nur wenn Sie das Passwort geheim eingegeben, wird nachfolgend eine
Webseite aufgebaut. Ansonsten passiert nichts weiter. Der Anwender sieht also
nur eine leere Seite.

Die nachfolgende Zeile zeigt
die Situation, mehr als eine Antwort richtig sein kann. Die Alternativen werden
in einer Oder-Beziehung verknüpft:

if
((pw=="geheim")||(pw=="GEHEIM"))

Wenn mehrere Bedingungen gleichzeitig erfüllt werden müssen,
verknüpft man sie als Und-Beziehung. Etwa wie in der nachfolgenden Zeile:

if
((pw=="geheim")&&(user=="admin"))

Grundsätzlich ist eine if-Anweisung zur Behandlung von einer
Situation alleine oft nicht ausreichend. Meist wird eine Alternative notwendig
sein. Für den Fall gibt es die Erweiterung else, die einen Block mit Anweisungen einleitet, welche immer dann (und nur dann) ausgeführt werden, wenn die vorangestellte
Bedingung der if-Anweisung
nicht erfüllt ist. Wenn bereits der if-Zweig ausgeführt wurde, wird der else-Zweig nicht
ausgeführt. Grundsätzliche Syntax ist immer die folgende:

if ([Bedingung]) {

…Anweisungen

}

else {

…alternative Anweisungen

}

Erstellen wir ein Beispiel so, dass es zwei Alternativen
gibt. Dazu soll zusätzlich die Bedingung in einer externen Funktion überprüft
und diese direkt in die if-Bedingung
notiert werden. Der Rückgabewert ist Boolesch.

<HTML>

<HEAD>

<SCRIPT
language="JavaScript">

function test(pass) {

if(pass=="geheim") return
true;

else return false;

}

var pw = prompt("Bitte geben Sie Ihr Passwort
ein","");

if(test(pw)) {

document.write(

"<H1 align=center>Herzlich Willkommen auf
meiner Homepage</H1>");

}

else {

document.write(

"<H3 align=center>Nur für
Mitglieder</H3>");

}

</SCRIPT>

</HEAD>

<BODY></BODY>

</HTML>

Listing 6.17: Der Einsatz von if-else

Das Script überprüft mit der Zeile

if(test(pass));,

ob eine Bedingung erfüllt ist. Diese Zeile beinhaltet die
Situation, dass anstelle eines explizit dort notierten Vergleichs ein
Funktionsaufruf steht. Diese dort angegebene Funktion liefert entweder true oder false zurück,
damit der nachfolgende Block entweder ausgeführt wird oder eben nicht. Beachten
Sie den Namen des Übergabewerts an die Funktion test(). Dieses wird in der Funktion als
Bezeichner einer lokalen Variablen fungieren. Die Funktion test() selbst hat auch eine interessante
Stelle:

if(pw=="geheim") return true;

Einmal sehen Sie die return-Sprunganweisung bei der Arbeit,
aber es gibt noch etwas von Interesse. Es fehlt der Block. Die Anwendung steht
ohne Blockstruktur unmittelbar hinter der if-Anweisung. Das geht immer dann, wenn
nur eine einzige Anweisung ausgeführt werden soll. Allgemein ist es aber
besser, wenn man eine Blockstruktur notiert. Dann ist man insbesondere
flexibler bei Erweiterungen. Bei falscher Eingabe des Passwortes wird eine
Alternativseite aufgebaut.

Das Beispiel soll nun so
umgeschrieben werden, dass mit dem konditionalen Operator (siehe dazu Seite 111) gearbeitet wird, der ja eine Kurzschreibweise
für if-else
ist. Allerdings ist er sehr schlecht zu lesen. Das nachfolgende Beispiel ist
von der Wirkung exakt identisch zu der vorherigen Variante.

<HTML>

<HEAD>

<SCRIPT
language="JavaScript">

function test(pass) {

return (pass=="geheim")?
true : false;

}

var pw = prompt("Bitte geben Sie Ihr Passwort
ein","");

document.write(test(pw)?

"<H1 align=center>Herzlich Willkommen auf
meiner Homepage</H1>" :

"<H3 align=center>Nur für
Mitglieder</H3>");

</SCRIPT>

</HEAD>

<BODY></BODY>

</HTML>

Listing 6.18: Der Einsatz von dem if-else-Operator

Der konditionale Operator wird zweimal verwendet. In der
Funktion test()
wird je nach Passwort true
oder false
als Rückgabewert geliefert, beim Aufruf der Funktion wird je nach Rückgabewert
entschieden, welchen Text document.write()
ausgeben soll.

Im else-Block
können bei Bedarf (wenn zwei Alternativen nicht genügen) weitere if-Anweisungen
notiert werden. Da in diesem Fall die if-Anweisung die einzige Anweisung des elseBlocks ist, kann das
Schlüsselwort if
direkt hinter else
notiert werden. Das sieht dann schematisch so aus:

if ([Bedingung 1]) {

…Anweisungen

}

else if ([Bedingung 2]) {

…alternative Anweisungen

}

else {

…alternative Anweisungen

}

Die Anzahl der Blöcke ist beliebig und ob der abschließende else-Block ohne if vorhanden ist,
ist nur eine Frage der Logik.

<HTML>

<BODY>

<SCRIPT
language="JavaScript">

var heute = new Date();

if(heute.getHours() < 12) {

document.write("<H1 align=center>Guten
Morgen</H1>");

}

else if(heute.getHours() < 17) {

document.write("<H1
align=center>Guten Tag</H1>");

}

else if(heute.getHours() < 22) {

document.write("<H1 align=center>Guten
Abend</H1>");

}

else {

document.write(

"<H1 align=center>Lasst mich endlich
schlafen!!</H1>");

}

</SCRIPT>

</BODY>

</HTML>

Listing 6.19: Verschachtelte if-else

Das Script bietet vier Alternativen. Je nach Tageszeit wird
eine andere Meldung in die Webseite geschrieben.

401 158
/if8

6.22: Moin-Moin

396 157
/if10

6.23: Zweite Alternative

401 158
/if9

6.24: Nu is aber Schluss

Beachten Sie, dass die Struktur darauf aufbaut, dass das
gesamte Konstrukt abgebrochen wird, wenn einer der Blöcke ausgeführt wurde.

6.7.3
Die switch-Fallunterscheidung

Wenn man im Ablauf eines Scripts mehr als zwei
Wahlmöglichkeiten unterscheiden muss, bietet sich in einigen Situationen eine
aufeinanderfolgende Notation von if-else-Anweisungen an. Dies kann aber bei einer größeren
Anzahl von Fallunterscheidungen recht unübersichtlich und mühsam werden. Es
gibt aber in JavaScript alternative Techniken, die in bestimmten Fällen eine
sinnvolle Lösung erlauben. Etwa die seit der JavaScript-Version 1.2
Fallunterscheidung über switch-case.
Wesentlicher Vorteil gegenüber der if-else-Struktur ist, dass Sie auf
einfache und elegante Weise mehr als zwei Fälle unterscheiden können. Nachteil
ist, dass man nur auf feste Werte und beispielsweise nicht direkt auf größer
oder kleiner prüfen kann. Die Syntax einer switch-Fallunterscheidung sieht i.a.
folgendermaßen aus:

switch([auswahl]) {

case [Fall 1]:

break;

case [Fall 2]:

break;

default:

break;

}

Mit dem Schlüsselwort switch leiten Sie die Fallunterscheidung
ein. Als Argumente wird in runden Klammern eingeschlossen eine Variable oder
ein Ausdruck angegeben, für dessen aktuellen Wert Sie die Fallunterscheidung
durchführen. Dies kann ein beliebiger Datentyp sein, der unter JavaScript
erlaubt ist (etwa eine Zahl, aber auch ein Text). Er wird auf Übereinstimmung
mit einem der nachfolgend hinter dem Schlüsselwort case notierten Werten geprüft. Die
einzelnen Fälle, zwischen denen unterschieden werden soll, werden untereinander
aufgelistet und innerhalb geschweifter Klammern als Blöcke hinter case notiert.
Optional ist eine default-Anweisung. Wenn keine der Auswahlmöglichkeiten auf den Wert der überprüften Variablen
zutrifft, wird der mit default
bezeichnete Fall ausgewählt.

<HTML>

<HEAD>

<SCRIPT
language="JavaScript">

var ergebnis=prompt(

"Wählen Sie "rot" oder
"schwarz" als Eingabe","");

switch(ergebnis) {

case "rot":

document.write("Der Gegner wählt rot.");

break;

case "schwarz":

document.write("Der Gegner wählt schwarz.");

break;

default:

document.write(

"Der Gegner hat das Spiel nicht kapiert.");

break;

}

</SCRIPT>

</HEAD>

<BODY></BODY>

</HTML>

Listing 6.20: switch-case

Beim Laden der Webseite werden Sie aufgefordert, entweder "rot"
oder "schwarz"
einzugeben[16]
(beachten Sie die maskierten Hochkommata in der JavaScript-Ausgabe). Dieser
Wert wird in einer Variablen gespeichert. In dem switch-Block wird der Fall ausgewählt,
dessen Prüfwert mit diesem Wert übereinstimmt. Die Anweisung break unterbricht
die weitere Abarbeitung dieser switch-Fallunterscheidung und springt hinter den gesamten
switch-Block.

356 116
/switch1

6.25: Eingabe des Prüfwertes

393 155
/switch2

6.26: Die Auswahl

Wenn keine der Auswahlmöglichkeiten auf den Wert der
überprüften Variablen zutrifft, wird der mit default bezeichnete Fall ausgewählt.

396 157
/switch3

6.27: Der Defaultfall

Die switch-Anweisung
hat einige Feinheiten zu bieten. Da ist einmal die Anordnung der case-Blöcke. Diese
Anordnung muss nicht in einer bestimmten Reihenfolge erfolgen. Das ist deshalb
klar, weil nur auf exakte Übereinstimmung geprüft wird. Es ist aber auch
möglich, das ein Wert in mehreren case-Blöcken überprüft wird. Das ist aber meist unsinnig,
weil der erste Treffer genommen wird und nachfolgende identische case-Prüfungen
irrelevant werden.

Eine andere Feinheit ist aber nicht so trivial. Ohne das am
Ende jedes Blocks notierte Schlüsselwort break (eine Sprunganweisung) würden nach
einem Treffer alle nachfolgenden Fälle ebenso ausgeführt. Unabhängig von einer
Übereinstimmung. Das ist in der Regel nicht gewünscht, kann aber auch sinnvoll
verwendet werden.

<HTML>

<HEAD>

<SCRIPT
language="JavaScript">

var ergebnis=prompt(

"Welchen Tag reisen Sie an?","");

switch(ergebnis) {

case "Montag":

document.write("Sie brauchen ein Zimmer für die
Nacht von Montag auf Dienstag.<br>");

case "Dienstag":

document.write("Sie brauchen ein Zimmer für die
Nacht von Dienstag auf Mittwoch.<br>");

case "Mittwoch":

document.write("Sie brauchen ein Zimmer für die
Nacht von Mittwoch auf Donnerstag.<br>");

case "Donnerstag":

document.write("Sie brauchen ein Zimmer für die
Nacht von Donnerstag auf Freitag.<br>");

case "Freitag":

document.write("Sie brauchen ein Zimmer für die
Nacht von Freitag auf Samstag.<br>");

case "Samstag":

document.write("Sie brauchen ein Zimmer für die
Nacht von Samstag auf Sonntag.<br>");

}

</SCRIPT>

</HEAD>

<BODY></BODY>

</HTML>

Listing 6.21: Verzicht auf break in switch-case

Beim Laden der Webseite werden Sie aufgefordert, einen
Anreisetag einzugeben. Dieser Wert wird in einer Variablen gespeichert. In dem switch-Block wird
der Fall ausgewählt, dessen Prüfwert mit diesem Wert übereinstimmt. Ab einem
Treffer werden alle Blöcke abgearbeitet.

356 116
/switch4

6.28: Eingabe des Prüfwertes

397 188
/switch5

6.29: swicht-case ohne break – Anreise
Dienstag

393 186
/switch6

6.30: swicht-case ohne break – Prüfwert
Freitag

Diese Anweisung steht erst in JavaScript 1.2 zur
Verfügung. Browser, die diese Anweisung nicht verstehen, werden mit einer
Fehlermeldung reagieren. Trotz der eleganteren Lösung über switch ist es sicherer, mehrere if-Abfragen hintereinander zu schalten.

6.7.4 while und do-while

Zwei eng verwandte und sehr oft eingesetzte
Kontrollfluss-Anweisungen sind die while- und die do-while-Schleifen.
Beide führen eine Prüfung einer Bedingung durch und wiederholen die im inneren
Block notierten Anweisungen solange, bis die Bedingung nicht mehr erfüllt ist.
Allgemeine Syntax ist folgende:

while ([Bedingung]) {

…Anweisungen

}

bzw.

do {

…Anweisungen

}

while ([Bedingung])

Die Bedingung können wie bei der if-Anweisung über Boolesche
Rückgabewerte von Funktionen, Boolesche Literale (true oder false) oder direkte Vergleiche überprüft
werden. Boolesche Literale sind gar nicht abwägig. Gerade true wird oft
verwendet, wenn man so genannte Endlosschleifen erzeugen will. Unter einer
Endlosschleife versteht man eine Wiederholung von Anweisungen im Inneren, wo
niemals eine Situation eintritt, die für eine Beendigung der Wiederholung
sorgt. Dies kann man sinnvoll nutzen – etwa eine Animation, wo eine Folge von
Grafiken immer wieder wiederholt werden sollen. Oder eine Hintergrundmusik. Es
kann aber auch als Fehler passieren. In diesem Fall bleibt oft nur die
Beendigung eines Programms oder gar ein Neustart des Rechners.

Die beiden Konstruktionen sind wie gesagt eng verwandt und
unterscheiden sich nur dadurch, dass bei der while- Schleife die Anweisungen im Block
überhaupt nicht durchgeführt werden, wenn die Bedingung bei Erreichen der
Schleifenkonstruktion falsch ist. Bei der do-while-Schleife (seit der Javaversion
1.2 vorhanden) werden die im Inneren notierten Anweisungen auf jeden Fall
einmal ausgeführt werden, bevor die Schleifenbedingung überprüft wird.
Verdeutlichen kann man sich das so, dass bei der while-Schleife die Überprüfung im
Quelltext vor dem Block mit den Anweisungen steht, bei der do-while-Schleife
hinter dem Block mit den Anweisungen.

Beide Schleifen benötigen in ihrem Inneren auf jeden Fall
eine Anweisung, die eine Situation schafft, mit der die Schleife abgebrochen
werden kann. Andernfalls erzeugen Sie eine Endlosschleife, was meist nur in
Ausnahmesituationen gewünscht ist. Normalerweise erfolgt die Generierung einer
Abbruchsituation darüber, dass die in der Bedingung geprüfte Variable im
Inneren so verändert wird, dass irgendwann die Bedingung nicht mehr erfüllt
ist. Es kann aber auch im Inneren mit einer zusätzlichen Anweisung (etwa der if-Anweisung) eine
Unterbrechung ausgelöst werden – etwa mit einem break oder return. Die nachfolgenden Beispiele
demonstrieren verschiedene Situationen.

<HTML>

<HEAD>

<SCRIPT language="JavaScript">

var zaehler=0;

while(zaehler <= 1000) {

document.write(zaehler + " ");

zaehler++;

}

document.write("<br>");

</SCRIPT>

</HEAD>

<BODY></BODY>

</HTML>

Listing 6.22:Vorgegebene Anzahl von Wiederholungen

Das erste Beispiel wiederholt einfach eine Ausgabe eine
vorgegebene Anzahl von Durchläufen.

396 357
/while2

6.31: Ausgabe durch eine Schleife

<HTML>

<HEAD>

<SCRIPT
language="JavaScript">

var pw;

while(pw!="geheim") {

pw=prompt("Geben Sie Ihr Passwort
ein","");

}

document.write("<h1>Willkommen</h1>");

</SCRIPT>

</HEAD>

<BODY></BODY>

</HTML>

Listing 6.23: Wiederholung einer Passwortabfrage
bis das Passwort stimmt

Das Beispiel demonstriert einen recht drastischen (und auf
keinen Fall praxisfähigen) Einsatz von while. Innerhalb der while-Schleife
wird der Besucher aufgefordert, ein Passwort einzugeben. Wenn es korrekt eingegeben
wird, wird die restliche Seite aufgebaut. Andernfalls wird die Schleife
wiederholt und der Anwender bekommt erneut das prompt()-Fenster vorgesetzt. Soweit gut.
Das Problem ist bei diesem recht einfachen Beispiel, dass der Anwender keine
Chance hat, ohne das Passwort aus der Schleife zu gelangen. Das bedeutet, er
kann weder das Laden der Webseite abbrechen, noch eine andere Webseite
auswählen und nicht einmal den Browser schließen (das prompt()-Fenster muss dazu zuerst
geschlossen werden, was zwar geht, aber die Schleife aktiviert ein neues prompt()-Fenster
in Bruchteilen von einer Sekunde). Die Abbrechen-Schaltfläche des
Fensters ist auch eine Lösung, denn diese schließt nur das Fenster. Die
Bedingung für den Abbruch der Schleife ist damit natürlich auf keinen Fall
gegeben.

356 116
/while1

6.32: Gefangen

Etwas praxisorientierter ist es, dem Anwender eine gewisse
Anzahl von Versuchen zu gestatten und dann abzubrechen. Das kann etwa mit den
JavaScript-Sprunganweisungen break
und return
erfolgen. Das Beispiel wird so aufgebaut, dass nach drei Versuchen mit return die
Schleife abgebrochen wird und entsprechend die Seite anders aufgebaut wird, als
wenn der Anwender das korrekte Passwort eingeben hat.

<HTML>

<HEAD>

<SCRIPT
language="JavaScript">

var pw;

var zaehler=0;

function test() {

while(pw!="geheim") {

pw=prompt("Geben Sie Ihr Passwort
ein","");

zaehler++;

if(zaehler>2) return 1;

}

}

if(test()!=1) document.write("<h1>Willkommen</h1>");

else document.write(

"<h1>Die Seite gibt es nur gegen
Passwort</h1>");

</SCRIPT>

</HEAD>

<BODY></BODY>

</HTML>

Listing 6.24: Maximal drei Wiederholung einer
Passwortabfrage bis das Passwort stimmt

Das umgebaute Beispiel nutzt eine globale Variable, um die
Anzahl der Versuche mitzuzählen. Wenn drei Fehlversuche erfolgt sind, bricht return die
Schleife quasi von innen heraus ab und liefert einen Rückgabewert, der an der
aufrufenden Stelle der Überprüfung verwendet wird.

Das Beispiel soll noch etwas verbessert und umgebaut werden.
Der Anwender bekommt einmal bei jedem Fehlversuch den Hinweis, dass das
Passwort falsch war und zudem wird der Rückgabewert auf Boolesch gesetzt, was
dann in der aufrufenden if-Schleife
eine direkte Notation des Funktionsaufrufs ohne expliziten Vergleich erlaubt.
Dazu kommen die do-while-Schleife
und eine Endlosschleife zum Einsatz. Die Bedingung zum Wiederholen ist immer true. Die Schleife
wird dennoch nach spätestens drei Versuchen abgebrochen. Der Abbruch erfolgt
durch die return-Anweisung.
Entweder, wenn das Passwort stimmt. Oder nachdem der Zähler eine gewisse Größe
erreicht hat. Beachten Sie, dass return unmittelbar die Schleife verlässt. Deshalb wird die
Meldung, dass das Passwort nicht stimmt, nur angezeigt, wenn ein Fehlversuch
erfolgt ist.

<HTML>

<HEAD>

<SCRIPT
language="JavaScript">

var pw;

var zaehler=0;

function test() {

do {

pw=prompt("Geben Sie Ihr Passwort
ein","");

zaehler++;

if(pw=="geheim") return true;

alert("Ihr Passwort ist falsch");

if(zaehler>2) return false;

}

while(true);

}

if(test())
document.write("<h1>Willkommen</h1>");

else document.write(

"<h1>Die Seite gibt es nur gegen
Passwort</h1>");

</SCRIPT>

</HEAD>

<BODY></BODY>

</HTML>

Listing 6.25: Maximal drei Wiederholung einer
Passwortabfrage mit Rückmeldung und Endlosschleife

177 116
/while1b

6.33: Hinweise

Gehen wir die Besonderheit der do-while-Schleife noch einmal genauer
an.

<HTML>

<HEAD>

<SCRIPT
language="JavaScript">

var niewahr=false;

do {

document.write("<h1>Das kommt
dennoch</h1>");

}

while(niewahr);

</SCRIPT>

</HEAD>

<BODY></BODY>

</HTML>

Listing 6.26: do-while-extrem

Das Beispiel demonstriert recht simple, dass unabhängig von
der Bedingung der Block mindestens einmal durchlaufen wird. Die Testvariable
ist konstant so gesetzt, dass die Bedingung nicht erfüllt ist dennoch wird die
im Inneren notierte Anweisung ausgeführt.

386 225
/while3

6.34: Die Seite wird erstellt, obwohl die
Bedingung nicht erfüllt ist

Wenn Sie logische Fehler in den Abbruchbedingungen einer
while-
bzw. do-while-Schleife
haben und diese nie erfüllt ist, erzeugen Sie eine Endlosschleife. In
Verbindung mit Mitteilungs- oder Dialogfenstern kann das fatal sein. Der
Browser lässt sich nicht mehr schließen. Sie müssen entweder den Task-Manager
einsetzen oder gar neustarten.

6.7.5
Die for-Schleife

Die letzte hier behandelte Programmflusskontrollanweisung
unter JavaScript ist die for-Schleife. In dieser Kontrollstruktur wird eine vorgegebene Anzahl von Durchgängen festgelegt. So oft wie angegeben, werden die Anweisungen im Inneren der Schleife ausgeführt. Bei jedem
Durchlauf wird die Zählvariable um eine Einheit (deren Größe in der Schleife
als letztes angegeben wird) hochgezählt. Grundsätzliche Syntax:

for ([Zählvariable];[Bedingung];[Schrittweite]) {

…Anweisungen

}

Zählvariable
ist die Deklaration der Zählvariablen mit gleichzeitiger Zuweisung eines
Startwertes.

Bedingung
definiert die Bedingung, wann die Wiederholung der Anweisungen abgebrochen
wird.

Schrittweite
ist eine Anweisung die angibt, wie die Zählvariable zu verändern ist. Das kann
sowohl ein positives, aber auch ein negatives Intervall sein. Abhängig davon
sollte die Abbruchbedingung sinnvoll gewählt werden. Das bedeutet, bei einem
positiven Intervall sollte in der Regel der Abbruchwert größer als der
Startwert sein (Prüfung der Bedingung auf kleiner), bei einem negativen
Intervall sollte der Abbruchwert dagegen kleiner als der Startwert sein (dann
muss die Bedingung auch auf größer als prüfen). Bei der Angabe der Schrittweite
kann man sogut wie immer auf die Veränderung um den Wert 1 zurückgreifen. Entweder ist ist
sowieso sinnvoll oder aber man konvertiert im Inneren der Anweisung mit einem
entsprechenden Umrechnungsfaktor. Nur in sehr seltenen Fällen muss man eine
andere Schrittweite wählen. Aus diesem Grund kommen bei der Angabe der
Schrittweite fast immer De- oder Inkrementoperatoren zum Einsatz.

Die for-Schleife
eignet sich hervorragend für alle Situationen, wo gleichartige Dinge eine
vorgegebene Anzahl mal ablaufen.

<HTML>

<HEAD>

<SCRIPT
language="JavaScript">

var zaehler;

var eingabe;

eingabe=prompt(

"Gegen Sie bitte eine Zahl zwischen 10 und 50
ein","");

for(zaehler=0;zaehler<=eingabe;zaehler++) {

document.write(zaehler + " ");

}

document.write("<P>");

for(zaehler=10;zaehler<=eingabe;zaehler=zaehler +
2) {

document.write(zaehler + " ");

}

document.write("<P>");

for(zaehler=100;zaehler>=eingabe-100;zaehler=zaehler
-7) {

document.write(zaehler + " ");

}

document.write("<P>");

</SCRIPT>

</HEAD>

<BODY></BODY>

</HTML>

Listing 6.27: Die for-Schleife

Beim Laden der Seite kann der Anwender einen Wert angeben,
der als Endwert des jeweiligen Schleifendurchlaufs verwendet wird.

356 116
/for1a

6.35: Die Eingabe des Wertes, bei dem die
Schleife abgebrochen werden soll

Die Zeile

for(zaehler=0;zaehler<=eingabe;zaehler++)

zählt von einem Startwert 0 jeweils in Einerschritten bis zu dem Endwert, den der
Anwender eingegeben hat. Dabei wird für die Intervallgröße der
Inkrement-Operator eingesetzt.

Die Zeile

for(zaehler=10;zaehler<=eingabe;zaehler=zaehler +
2)

zählt von einem Startwert 10 jeweils in Zweierschritten bis zu dem
Endwert, den der Anwender eingegeben hat. Das sind also weniger Durchläufe als
bei der ersten Schleife.

Die Zeile

for(zaehler=100;zaehler>=eingabe-100;zaehler=zaehler-7)

zählt von einem Startwert 100 rückwärts jeweils in
Siebenerschritten bis zu dem Endwert, den der Anwender eingegeben hat, minus 100. Die
Überprüfung der Bedingung muss hier auf Kleiner bzw. Kleinergleich erfolgen.

407 182
/for1b

6.36: Die Anzeige bei Eingabe 42

Die for-Schleife eignet sich wie gesagt
hervorragend zum Zugriff auf von Arrays (siehe Seite 85). Erinnern Sie sich an das Beispiel mit der
Berechnung der Lottozahlen (siehe Seite 62)? Hier spielen wir eine
elegantere Variante durch, die Arrays in Verbindung mit der for-Schleife
einsetzt und so den Quelltext viel kompakter, besser wartbar und flexibler
gestaltet.

<HTML>

<SCRIPT language="JavaScript">

function lottoZahlen() {

var lottoArray = new Array(7);

for(i=0;i<7;i++) {

lottoArray[i] =
Math.round(Math.random()*49);

}

for(i=0;i<6;i++) {

document.write("Zahl " +
(i+1) + ": " + lottoArray[i] + "<br>");

}

document.write("Zusatzahl:
" + lottoArray[6] + "<br>");

}

</SCRIPT>

<BODY
onload="lottoZahlen()"></BODY>

</HTML>

Listing 6.28: Die for-Schleife in Verbindung mit
Arrays

Das Beispiel füllt mit einer for-Schleife ein Array mit Zufallszahlen
und gibt diese zusammen mit Textbausteinen in einer weiteren Schleife wieder
aus. Theoretisch kann das auch mit einer Schleife erfolgen. Beachten Sie aber,
dass die Ausgabe einen aus der Reihe fallenden Textbaustein verwendet. Deshalb
wird die Zusatzzahl gesondert behandelt. Das kann man zwar innerhalb einer
Schleife mit einer Zusatzanweisung (etwa if) lösen, aber zwei for-Schleifen sind
genauso effektiv.

190 399
/for2

6.37: Ein Array wird mit for gefüllt und
ausgegeben

Das Beispiel setzt nun voraus, dass Sie bei der Angabe des Abbruchkriteriums wissen, wie groß das Array ist. Es gibt aber viele
Situationen, wo Sie das bei der Erstellung des Scripts nicht wissen können. Das
nachfolgende Beispiel demonstriert so eine Situation. Ein Anwender bekommt von
dem Script eine zufällig generierte Kombinationen aus Zeichen als Passwort
mitgeteilt. Dieses wird dazu zuerst in einem Array abgelegt. Die Anzahl der
Zeichen des Passwortes wird dabei zufällig zwischen 5 und 8 ermittelt. Das bedeutet, die Größe des
Arrays verändert sich von Fall zu Fall. Die Lösung basiert darauf, dass Arrays
Objekte sind und diese beinhalten immer die Eigenschaft length, in der die Größe des Objekts
gespeichert ist. Damit kann man das Abbruchkriterium der for-Schleife dann individuell berechnen.

<HTML>

<SCRIPT
language="JavaScript">

function komponiere() {

var pwArray = new Array();

var textBasis =
"abcdefghijklmnopqrstuvwxyz1234567890";

var abbruch=0;

var i=0;

while(true) {

zeichenNr =
Math.round(Math.random()*36);

abbruch = 0.6 + Math.random();

pwArray[i] =
textBasis.slice(zeichenNr,zeichenNr + 1);

i++;

if (((i>4)&&(abbruch>1)) || (i>7))
break;

}

document.write("Das ist Ihr Passwort. Es ist
" +

pwArray.length +

" Zeichen gross. Notieren Sie sich das Passwort
bitte.<p>")

for(i=0;i<pwArray.length;i++)

document.write(pwArray[i]);

}

</SCRIPT>

<BODY
onload="komponiere()">

</BODY>

</HTML>

Listing 6.29: Die for-Schleife in Verbindung mit
dynamisch in der Größe festgelegten Arrays

Das Beispiel verwendet die slice()-Methode eines String-Objektes,
um aus einem als Textbasis fungierenden Textstring zufällig Zeichen zu extrahieren.
Wir setzen dazu eine Endlosschleife auf Basis von while ein. Als Abbruchkriterium gilt
entweder, dass die Anzahl der Zeichen mehr als 4 ist und ein Zufallswert einen
bestimmten Wert überschreitet oder aber, dass die Anzahl der Zeichen größer als
7 ist. Die for-Schleife muss
also auf ein dynamisch in der Größe festgelegtes Array reagieren.

397 166
/for3a

6.38: Einmal so groß

400 180
/for3b

6.39: Und das andere Mal so groß

In diesem Zusammenhang soll eine interessante Variante der for-Schleife
demonstriert werden. Ein Spezialfall der for-Schleife ist die for…in-Schleife. Diese durchläuft automatisch alle Einträge eines Arrays (insbesondere, ohne darüber hinaus zu schießen).

<HTML>

<SCRIPT
language="JavaScript">

function zufall() {

var meinArray = new Array();

var groesse = Math.round(Math.random()*100);

for(i=0;i<groesse;i++)

meinArray[i] =
Math.round(Math.random()*100);

for (i in meinArray)

document.write(meinArray[i] + ",
");

}

</SCRIPT>

<BODY
onload="zufall()">

</BODY>

</HTML>

Listing 6.30: Verwendung von for…in

Das Beispiel berechnet einen zufälligen Wert, der dann die
Größe eines Arrays bestimmt.

397 179
/for4a

6.40: Einmal so

393 178
/for4b

6.41: Einmal so

Natürlich wird die Konstellation, aus der sich die Größe
eines Arrays ergibt, in der Realität selten so trivial sein. Die Technik ist in
der Tat in vielen Situationen sehr nützlich.