Eine weitere Methode zum Erzeugen von Objekten ist die Verwendung von Konstruktorfunktionen. Dies geschieht in zwei Schritten:
Um einen Objekttyp zu definieren, wird eine Funktion (Konstruktorfunktion) geschrieben, die den Namen, die Eigenschaften und Methoden des Objekttyps spezifiziert. In der Funktion wird auf das definierte Objekt mittels this referenziert.
|
function car (make, model, year) { this.make = make; this. model = model; this.year = year; } |
Jetzt können Objekte vom Typ "car" deklariert werden.
|
myCar = new car ("VW", "Golf V5", "1999"); yourCar = new car ("Audi", "A3", "1999"); |
Die Werte werden den Eigenschaften in Aufschreibungsreihenfolge zugewiesen, d.h., das Objekt myCar hat make = "VW", model = "Golf V5" usw.
Ein Objekt kann als Eigenschaft ein anderes Objekt enthalten.
Gehen wir von einem Objekttyp "person" aus.
|
function person (name, age, sex) { this.name = name; this.age = age; this.sex = sex; } philipp = new person("Philipp", 15, "m"); dominik = new person("Dominik", 10, "m"); melanie = new person("Melanie", 40, "f"); |
Wenn nun die Definition von "car" abgeändert wird in:
|
function car (make, model, year, owner) { this.make = make; this. model = model; this.year = year; this.owner = owner; } |
dann können Objekte erzeugt (instanziiert, instantiate) werden durch:
|
car1 = new car ("BMW", "320", 1996, philipp); car2 = new car ("VW", "Lupo", 2000, dominik); |
Im o.a. Beispiel werden neben Literalen (z.B. "BMW") Objekte dominik und philipp als aktuelle Parameter der Konstruktorfunktion mitgegeben.
Die Werte der Eigenschaften dieser Objekte sind durch
|
car1.owner.year = 16; // wenn Philipp den nächsten
Geburtstag hat car2.owner = melanie; // bei Besitzerwechsel |
anzusprechen.
Wenn Objekte deklariert sind, können Eigenschaften und Methoden nachträglich hinzugefügt werden, etwa durch:
| car1.color = "black"; |
Achtung: dadurch hat nur car1, nicht car2 die Eigenschaft color erhalten!
Soll die Eigenschaft für alle Objekte des Typs car gelten, so ist die Konstruktorfunktion abzuändern oder man verwendet eine spezielle Eigenschaft, die alle Objekte haben: prototype.
Das nachfolgende Beispiel führt die Eigenschaft color für alle Objekte des Typs car ein und weist der Eigenschaft color des Objektes car1 den Wert "red" zu.
|
car.prototype.color = null; car1.color = "red"; |
Eine Methode ist eine Funktion, die zu einem Objekt gehört. Eine Methode wird wie eine normale Funktion definiert und dann einem Objekt zugeordnet durch:
object.methodName = fucktionName
wobei object ein existierendes Objekt ist, methodName ist der die Methode identifizierende Name und fucktionName der Name der zugeordneten Funktion.
Eine Methode wird innerhalb eines Objektes aufgerufen durch:
object.methodName ( params );
Man kann eine Methode innerhalb der Konstruktorfunktion hinzufügen. Dadurch wird die Methode dem Objekttyp zugeordnet.
|
function displayCar() {
var result = "A Beautiful " + this.year + " " + this.make + " " + this.model + "<hr>" document.write(result); }
function car(make, model, year, owner) {
|
Damit kann man dann die Methode wie folgt aufrufen:
|
car1.displayCar(); car2.displayCar(); |
Das Beispiel sieht somit in Gänze folgendermaßen aus:
In den Beispielen ist öfter ein Objekt nicht durch seinen Namen angegeben, sondern durch this referenziert.
this ist ein reserviertes Wort von JavaScript und wird innerhalb von Methoden verwendet, um das aktuelle Objekt anzusprechen.
Definieren Sie einen Objekttyp "account" (Bankkonto) mit den Eigenschaften
"balance" (Saldo),
"owner" (Kontoinhaber)
und den Methoden
"drawIn" (Einzahlen erhöht Saldo),
"drawOut" (Abheben vermindert Saldo) und
"printBalance" zur Ausgabe des Kontostandes.
Führen Sie mehrere Transaktionen (Ein- und Auszahlungen) für ein Konto durch und zeigen Sie nach jeder Transaktion den Kontostand an.
Hier werden die vordefinierten Objekte behandelt, die im Sprachkern von JavaScript enthalten sind:
Ein Array (in anderen Sprachen auch Feld genannt) ist eine Ansammlung von Elementen. In JavaScript gibt es den Typ Array nicht explizite (so wie z.B. in Pascal), man kann Arrays verwenden, indem man die Eigenschaften und Methoden des Objekttyps Array verwendet.
In JavaScript ist ein Array eine geordnete Menge von Werten, die einen Namen hat und auf deren Element man indiziert zugreift.
So kann ein Array mit Namen emp alle Angestellten einer Firma beinhalten. Der Index gibt die (fortlaufende) Nummer des Angestellten an, so sind die Angestellten dann emp[1], emp[2], emp[3], usw.
Array könne auf zwei Arten erzeugt werden:
wobei arrayObjectName entweder der Name eines neuen Objektes oder eine Eigenschaft eines existierenden Objektes ist. elementI ist ein Element des Arrays; bei dieser Art der Erzeugung ist dann die Länge des Array N und die Elemente haben definierte Werte. Bei der zweiten Art der Erzeugung umfasst das Array arrayLength Elemente, die Werte sind undefiniert.
Die folgende Anweisung erzeugt ein Array von 5 Elementen:
| stack = new Array (5); |
Arrayliterale können wie folgt erzeugt werden:
| cars = ["VW", "BMW", "Audi", "Honda"]; |
Man kann einem Element eines Array wie folgt einen Wert zuweisen:
|
stack[1] = 12; stack[2] = -1; stack[3] = 69; |
Die Elemente eines Arrays werden von 0 angefangen "durchnummeriert".
Somit hat das o.a. Array "cars" die Elemente cars[0] == "VW" , ... cars[3] == "Honda".
Eine Eigenschaft eines Arrays ist "lemgth". Sie gibt die Anzahl der Elemente des Array an.
Das nachfolgende Beispiel demonstriert die Verwendung von Arrays.
In JavaScript sind Arrays dynamische Objekte, d.h. auch wenn ein Array mit Länge 10 definiert wurde, wie im obigen Beispiel, kann man noch beliebig viele weitere Elemente hinzufügen. In anderen Sprachen, wie z.B. C ist ist nicht möglich.
Das folgende Programm speichert Benutzereingaben in einem Array ab und ermittelt die größte Zahl und gibt sie aus.
Schreiben Sie ein Programm, das Messwerte (Floats) einliest und auswertet. Ermitteln Sie folgende Größen:
Maximum,
Minimum,
Mittelwert
Als Ergebnis sollen die o.a. Größen zusammen mit der Position innerhalb der Messreihe in einer Tabelle ausgegeben werden.
Das Array Objekt beinhaltet folgende Methoden:
Diese Methoden werden an hand von Beispielen verdeutlicht.
Schreiben Sie ein Programm, das eine FIFO (LIFO) Speicher simuliert. Definieren Sie dazu einen Objekttyp FIFO (LIFO) als Array und verwenden Sie die o.a. Methoden für Arrays.
Lösung FIFO
Lösung LIFO
Realisieren Sie eine rekursive Funktion printArray, die als Parameter ein Objekt vom Typ Array hat. Die Funktion soll die Elemente der Reihe nach ausgeben.
In JavaScript sind mehrdimensionale Array möglich.
Das nachfolgende Beispiel erzeugt eine Matrix (zweidimensionales Array) Strings und gibt die Elemente aus..
Man sieht, dass zum Zugriff die Indizes der einzelnen Dimensionen in Klammern hintereinander geschrieben werden, so ist z.B. a[i][j] die Zeile i mit Spalte j.
Die Matrizenmultiplikation ist wie folgt definiert:
Sei A eine (m,n) Matrix und B eine (n,r) Matrix.
C=A+B ist wie folgt definiert:

Beispiel:

Schreiben Sie ein Programm für die Matrizenmultiplikation.
Die Binomialkoeffizienten können nach folgenden zwei Verfahren berechnet werden.
Verfahren 1:

Verfahren 2:
biko(n,0) = 1
biko(n,n) = 1 für n=1,2,3,..
biko(n,k) = biko(n-1,k-1) + biko(n-1,k) für n=2,3,4,..
und k=1,2,3....,n-1
Dadurch ist das Pascalsche Dreieck bestimmt, z.B. für n=5:
| biko | 0 | 1 | 2 | 3 | 4 | 5 |
| 1 | 1 | 1 | ||||
| 2 | 1 | 2 | 1 | |||
| 3 | 1 | 3 | 3 | 1 | ||
| 4 | 1 | 4 | 6 | 4 | 1 | |
| 5 | 1 | 5 | 10 | 10 | 5 | 1 |
Dabei steht im Schnittpunkt der n-ten Zeile und der k-ten Spalte der Wert für biko(n,k).
a) Schreiben Sie ein Programm, das das Pascalsche Dreieck n=5 berechnet. Verwenden Sie das zweite Verfahren.
b) Entwickeln Sie eine Funktion biko(n,k), die den Binomialkoeffizienten von n und k ermittelt. Entwickeln Sie weiterhin eine Funktion, die eine Matrix als HTML-Tabelle ausgibt. Verwenden Sie diese Funktionen, um eine Matrix mit den Werten der Binomialkoeffizienten zu füllen und auszugeben.
In herkömmlichen Programmiersprachen wie C ist nur der indizierte Zugriff über die numerische Position innerhalb des Array (so wie wir es bis jetzt gesehen haben) möglich. D.h. man ordnet jedem numerischen Index ein Element zu.
| a = new Array("Auto","Yacht","nichts"); |
Im o.a. Beispiel wird also folgende Zuordnung gemacht:
0 -> "Auto"
1 -> "Yacht"
2 -> "nichts"
JavaScript erlaubt darüberhinaus den assoziativen Zugriff.
Nehmen wir an, wir wollten eine Zuordnung machen, etwa
"Jim" -> "Auto"
"John" -> "Yacht"
"James" -> "nichts"
dann kann dies wie folgt in JavaScript angegeben werden:
|
a = new Array();
a["Jim"] = "Auto"; |
Die Verwendung assoziativer Array ist nachfolgend gezeigt.
Der Objekttyp Boolean ist ein Objekttyp zur Aufnahme von Wahrheitswerten.
Ein Objekt wird angelegt durch:
booleanObjectName = new Boolean(value)
wobei booleanObjectName der Name des Objektes ist und value der Wert.
Vorsicht:
Es besteht ein Unterschied zwischen den booleschen Werten true bzw. false und einem Objekt von Typ Boolean mit Wert true bzw. false : Jedes Objekt, also auch Objekte vom Typ Boolean, dessen Wert undefinded oder null ist, wird zu true ausgewertet, wenn es in einer Bedingung auftaucht.
JavaScript hat keinen eigenen Datentyp für Datum und Uhrzeit. Diese Informationen werden durch den Objekttyp Date abgehandelt, der eine Menge von Methoden zum Setzen, Manipulieren und Abfragen bereitstellt.
In JavaScript wird die Zeit so wie in Java oder in den Shells von Unix behandelt. Eine Zeitangabe wird stets in der Anzahl der Millisekunden seit dem ("Unix Urknall" ), dem 1.1.1970 00:00:00 Uhr angegeben bzw. gespeichert.
Ein Date Objekt wird angelegt durch:
dateObjectName = new Date([parameters])
wobei dateObjectName der Name des Objektes ist und parameters die optional anzugebenden Parameter. Als Parameter sind erlaubt:
Alle Methoden verwenden die in der nächsten Auflistung gezeigten Konventionen:
| Angabe | Bereich |
| Sekunden | 0 - 59 |
| Stunden | 0 - 23 |
| Tag | 1 - 31 |
| Wochentag | 0 - 6 (0=Sonntag) |
| Monat | 0 - 11 (0=Januar) |
| Jahr | Anzahl Jahre seit 1990, d.h. 2010 wird als 110 dargestellt. |
Die folgenden Methoden umfasst Date.
| Methode | Bedeutung |
| getDate() | liefert den Tag |
| getDay() | liefert die Nummer des Wochentages |
| getHours() | liefert die Stunden |
| getMinutes() | liefert die Minuten |
| getMonth() | liefert den Monat |
| getSeconds() | liefert die Sekunden |
| getTime() | Anzahl Millisekunden seit 1.1.70 0:0:0 Uhr |
| getTimeZoneOffset() | Zeitverschiebung in Minuten der lokalen Zeit gegenüber der GMT (Greenwhich Mean Time) |
| getYear() | Anzahl Jahre seit 1970 |
| parse(DateString) | Anzahl Millisekunden aus DateString, z.B. date.parse("Aug 17, 1999"); |
| setDate(Day) | legt den Monatstag fest |
| setHours(Hour) | legt die Stunden fest |
| setMinutes(Minute) | legt die Minuten fest |
| setMonth(Month) | legt den Monat fest |
| setSeconds(Second) | legt die Sekunden fest |
| setTime(Millisecs) | setzt Datum/Zeit auf Wert, der durch 1970 0:0:0 + millisecs bestimmt ist |
| setYear(Year) | legt Jahr fest |
| toGMTString() | konvertiert Datum/Uhrzeit umgerechnet in GMT Zeitzone in einen String |
| toLocalString() | konvertiert Datum/Uhrzeit der lokalen Zeitzone in einen String |
| UTC(Year,Month,Day,[Hour],[Min],[Sec]) | liefert Anzahl Millisekunden seit Urknall in der GMT Zeitzone |
Das nachfolgende Beispiel verwendet diese Methoden, um die Zeit anzuzeigen.
Die aktuelle Uhrzeit wird im o.a. Beispiel nur einmal angezeigt, sie wird nicht aktualisiert. Das folgende Beispiel zeigt, wie man eine "laufende Uhr" einfach durch "setTimeout" programmieren kann.
Entwickeln Sie eine Funktion, die die Tagesdifferenz von zwei Datums-Parametern berechnet.
Die Funktion getYear liefert die Anzahl der Jahre seit 1900. Um eine vierstellige Jahreszahl zu erhalten, muss also auf das Ergebnis 1900 addiert werden (101+ 1900 = 2001). Einige Browser liefern aber bereits bei getYear eine vierstellige Zahl, wodurch dann falsche Ergebnisse produziert werden (2001 + 1900 = 3901). ECMA definierte deshalb die Funktion getFullYear, die vierstellige Jahreszahlen liefert. Diese Funktion wird nicht von allen Browsern unterstützt.
Man kann das Problem wie folgt lösen:
|
var today = new Date(); var year = today.getYear(); year = (year < 1900) ? jahr += 1900: year; |
Der Objekttyp Math umfasst Eigenschaften und Methoden für mathematische Konstanten und Funktionen, wie PI oder sin.
Die nachfolgende Tabelle beschreibt die Methoden:
| Methode | Bedeutung |
| abs(x) | Absolutwert |
| ceil(x) | Runden auf nächst höhere ganze Zahl |
| cos(x) | Cosinus |
| floor(x) | Runden auf nächst niedrigere ganze Zahl |
| random() | Zufallszahl zwischen 0 und 1 |
| round(x) | Runden |
| sin(x) | Sinuns |
| sqrt(x) | Wurzel |
| asin() | Inverse Sinusfunktion |
| atan() | Inverse Tangensfunktion |
| exp(x) | Exponentiation zur Basis e |
| log(x) | Logarithmus zur Basis e |
| acos() | Inverse Cosinusfunktion |
| tan(x) | Tangens |
Vordefinierte Konstanten sind:
| Konstante | Bedeutung |
| E | Eulersche Zahl |
| LN2 | natürlicher Logarithmus von 2 |
| LN10 | natürlicher Logarithmus von 10 |
| LOG2E | binärer Logarithmus von 2 |
| LOG10E | binärer Logarithmus von 10 |
| PI | Pi |
| SQRT1_2 | Wurzel von 0,5 |
| SQRT2 | Wurzel von 2 |
In JavaScript kann man keine Math-Objekte explizite erzeugen. Man verwendet einfach den Objekttyp zusammen mit Variablen oder Literalen.
| Beispiel 4.3-19 | |
Im Zusammenhang mit Objekten erlaubt JavaScript auch ein Statement with:
| Beispiel 4.3-20 | |
Der Objekttyp Number beinhaltet als Eigenschaften Konstanten für die Größen der abbildbaren Objekte.
| Konstante | Bedeutung |
| Max_VALUE | größte darstellbare Zahl |
| MIN_VALUE | klinste darstellbare Zahl |
| NaN | "Not a Number" Wert |
| NEGATIVE_INFINITY | minus Unendlich |
| POSITIVE_INFINITY | Unendlich |
| Beispiel 4.3-21 | |
Schreiben Sie ein Programm, das aus 10 Zufallszahlen zwischen 0 und 100 die größte Zahl ermittelt.
Ermitteln Sie die Nullstellen der Funktion
f(x)=4x-cos(x) mit Hilfe des folgenden Iterationsverfahrens (Newton Iteration):

Es existiert ein Objekttyp RegExp zur Bearbeitung von regülären Ausdrücken. Dieser Objektyp wird später behandelt.
In JavaScript gibt es einen Objekttyp für Zeichenketten: String.
String ist als Hülle anzusehen, die den elementaren Typ umgibt und so Methoden zur Stringbearbeitung bereit stellt.
Stings sollten nicht mit Stringliteralen verwechselt werden, wie folgendes Beispiel zeigt:
|
s1="String 123"; //String Literal s2=new String ("String 123") // String Object |
Alle Methoden für String Objekte können auf String Literale angewendet werden - JavaScript konvertiert den Literal in ein temporäres String Objekt.
Trotzdem existieren Unterschiede:
| Beispiel 4.3-22 | |
Die am häufigsten verwendete Eigenschaft von String ist length, die die Anzahl der Zeichen des Strings liefert.
String hat zwei Arten von Methoden:
| Beispiel 4.3-23 | |
Die folgende Tabelle zeigt die Methoden von String:
| Methode | Bedeutung |
| anchor | erzeugt einen HTML Anker |
| big, blink, bold, fixed, italics, small, sub, sup, | HTML Formate |
| link | erzeugt einen HTML Link |
| charAt, charCodeAt | liefert das Zeichen oder den Kode des Zeichens an der mitgegebenen Position |
| indexOf, lastIndexOf | liefert die Position des Teilstrings im String oder die letzte Position des Teilstrings im String |
| concat | Konkatenation von Strings |
| split | teilt einen String |
| substring, substr | liefert einen Teilstring, der spezifiziert ist durch Start- und Endposition oder Startposition und Länge |
| match, replae, search | wird bei RegExp behandelt |
| toLowerCase, toUpperCase | konvertiert in Groß- bzw. Kleinbuchstaben |
| slice | splittet einen Teil eines Strings ab und liefert einen neuen String |
| Beispiel 4.3-24 | |
Anstatt die Methode mit exakter Aufrufsystematik zu beschreiben, werden exemplarische Beispiele gezeigt. Im Referenzhandbuch ist die Systematik beschrieben.
| Beispiel 4.3-25 | |
| Beispiel 4.3-26 | |
| Beispiel 4.3-27 | |
| Beispiel 4.3-28 | |
| Beispiel 4.3-29 | |
Die Anzahl der Auftreten eines Stings kann mit den Methoden einfach programmiert werden:
| Beispiel 4.3-30 | |
| Beispiel 4.3-31 | |
Somit entspricht das o.a. Beispiel in HTML:
Click to return to <a href="http://www.fbi.h-da.de">FHD</a>
| Beispiel 4.3-32 | |
Entwickeln Sie ein Programm, dass die Anzahl der Worte und Zeichen in einem String (mit prompt eingeben lassen) ausgibt. Ein Wort ist dabei eine Zeichenfolge, die weder Leerzeichen noch Tabulatoren enthält.
Fehlerbehandlung wurde von von ECMA in ECMAScript integriert. Bisher wird es nur von Netscape (>=6.x) und Microsoft (>=5.x) unterstützt.
Die Fehlerbehandlung basiert auf dem Konzept der Exception Handler durch die (von C++ bekannten) Anweisungen try und catch.
Nach try steht ein Anweisungsblock, der eine kritische Operation durchführt; der Block nach catch gibt an, was passieren soll, wenn im try-Block ein Fehler aufgetreten ist. Der catch-Block fängt also Fehler im try-Block ab.
| Beispiel 4.4-1 | |
Im o.a. Beispiel wird die Methode test des Objektes xyz aufgerufen. Dieses Objekt existiert aber nicht - ein Fehler ist aufgetreten. Normalerweise würde der Browser einen Fehler melden. Statt dessen wird hier ein alert-Fenster mit einer Meldung erscheinen, so wie es im catch-Block festgelegt ist.
Im catch-Block können JacaScript Anweisungen stehen. Sie werden nur bei Eintreten eines Fehlers ausgeführt. Folgen im try-Block weitere Anweisungen, werden sie im Fehlerfall nicht mehr behandelt. Nach Abarbeitung des catch-Blocks im Fehlerfall, wird mit der Abarbeitung der Anweisungen nach der try-catch-Anweisung fortgefahren.
Tritt im try-Block kein Fehler auf, wird der catch-Block nicht ausgeführt.
Die in runden Klammern angegebene Variable wird im Fehlerfall einem Error-Objekt zugewiesen. Über dieses Objekt, d.h. seine Eigenschaften, kann man Informationen über en eingetretenen Fehler bekommen.
| Beispiel 4.4-2 | |
| Beispiel 4.4-3 | |
Nicht jede JavaScript Implementierung unterstützt das Exception Handling.
Die folgende Tabelle zeigt die vordefinierten Fehlertypen:
| Fehlertyp | Bedeutung |
| EvalError | gibt an, dass ein Fehler im Zusammenhang mit der Funktion eval() aufgetreten ist |
| RangeError | weist auf Überschreitungen des Wertebereiches von Objekten hin |
| ReferenceError | tritt bei nicht gültigen Referenzen auf |
| SyntaxError | Fehler beim Parsen von Quellkode, z.B. bei der eval-Funktion oder bei einem regulären Ausdruck |
| TypeError | zeigt an, dass es beim Konvertieren von Typen Unzulänglichkeiten gibt |
| URLError | Fehler im Zusammenhang mit einer Web Adresse |
Achtung:
In Java können mehrere catch-Blöcke (für unterschiedliche Typen) zu einem try-Block gehören. Dies ist in JavaScript nicht möglich (wegen "loose typing")
Einen Ausweg bietet die Verwendung des instanceof-Operators, der zum Testen auf Zugehörigkeit zu einem Objekttyp vorhanden ist.
Variable instanceof ObjectTyp liefer true, wenn Variable zum Objekttyp ObjectTyp gehört.
Somit kann man in der try-catch Anweisung wie folgt vorgehen:
|
try { x.y.z.test(); } catch (e) { if (e instanceof TypeError) { alert("Error 1"); else if (e instanceof ReferenceError) alert("Error 2); else alert("Error 3"); } |
Wie in Java, so kann man auch in JavaScipt einen finally-Block angeben. Es ist sicher gestellt, dass die Anweisung im finally-Block immer ausgeführt wird; also auch wenn die Ausnahme nicht eintritt.
| Beispiel 4.4-4 | |
Um auf eigene Ausnahmen reagieren zu können, kann man selbst Error Objekte erzeugen.
Dann wird eine Ausnahme durch die Anweisung throw ausgelöst.
| Beispiel 4.4-5 | |
new Error("Text") erzeugt ein Error Objekt mit der Eigenschaft message.
Error ist ein allgemeines Objekt, um Fehler zu behandeln. Es ist auch möglich, Objekte für die vordefinierten Fehlertypen zu verwenden:
| new TypeError("Text"); |
In JavaScript kann man nicht nur Error Objekte verwenden, um auf Fehler zu reagieren. Selbst definierte Objekte sind ebenfalls möglich:
| Beispiel 4.4-6 | |
Zunächst ist ein eigener Objekttyp "MeinFehler" definiert. In der Funktion test wird dann ein solches Objekt erzeugt.
Mit dem Operator instanceof wird geprüft, von welchem Objekttyp e ist; in Abhängigkeit davon wird reagiert (mittels alert).