Informatik 2 - Einführung in JavaScript

Werbung
Informatik 2
Einführung in JavaScript
Prof. Dr.-Ing. Holger Vogelsang
[email protected]
Inhaltsverzeichnis








Prinzipien (3)
Einstieg (11)
Funktionen (38)
Objekte und Vererbung (46)
Module (63)
Private Daten (69)
DOM-Zugriffe (72)
Ende (83)
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
2
Prinzipien
Übersicht
Grafische
Oberflächen
Übersicht
Datenstrukturen
ADTs
Typinfo.,
I/O
Annotationen
JavaScript
Prinzipien
Holger Vogelsang
Layouts
Ereignisse
Datenstrukturen
in Java
Laufzeittypinfo.
Einstieg
Widgets
Grafikoperationen
Elementare
Datenstrukturen
Grafikwidgets
Effekte,
Animationen
Iteratoren
Hashtabellen
Bäume
Module
Private
Daten
DOMZugriffe
Offene
Punkte
Graphen
Ein-,
Ausgabe
Funktionen
Objekte und
Vererbung
Informatik 2 - Einführung in JavaScript
3
Prinzipien
Motivation


Eigenschaften von JavaScript
Laufzeitumgebungen
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
4
Prinzipien
Skriptsprachen
Was sind die Merkmale einer Skriptsprache (nicht genau definiert)?

Häufig über einen Interpreter ausgeführt, keine Compilierung erforderlich

Implizit deklarierte Variablen, schwache Typisierung: Variablentypen werden zur Laufzeit
erkannt  Ducktyping

Dynamische Programmänderung: Hinzufügen von Klassen, Methoden und Attributen zur
Laufzeit

Automatische Speicherverwaltung wie in Java und C#

Oft weniger „geschwätzig“  höherer Abstraktionsgrad, domänenspezifische Sprachen
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
5
Prinzipien
Skriptsprachen
Vorteile von Skript-Sprachen:

schnelle Entwicklungen (Rapid Prototyping)

kein Compiler-Schritt erforderlich

Austausch von Code zur Laufzeit

Domain-spezifische Sprachen
Nachteile von Skript-Sprachen:
− Typfehler erst zur Laufzeit sichtbar  viel mehr testen
− schlechte IDE-Unterstützung (Typen fehlen), Vorschläge wie hier bei Java sind nicht so genau
möglich:
− geringere Ausführungs-Geschwindigkeit
− weniger „Best Practices“ vorhanden
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
6
Prinzipien
Geschichte der Sprache






1995: LiveScript im Browser Netscape Navigator 2.0
1996: Nach Umbenennung JavaScript 1.1 im Netscape Navigator 3 und im Internet Explorer
3.0.
1998: JavaScript 1.3 wird im Standard ECMA-262 festgehalten.
…
2008: JavaScript 1.8.5 wird im Standard ECMAScript 5 Compliance festgehalten  darauf
basiert die Einführung in der Vorlesung
Die Syntax von Java ähnelt der von JavaScript, die Semantik ist teilweise aber deutlich anders.
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
7
Prinzipien
Eigenschaften

Laufzeitumgebung auf dem Client: Z.B. im Browser zur Manipulation von Web-Seiten.
URL-Aufruf
Antwort
Browser
JavaScriptFunktionen


Web Server
lesen
Aufruf
HTML-Seiten, Bilder,
JavaScript-Dateien,
CSS-Dateien …
(Dateisystem)
JavaScript läuft in einer „Sandbox“ und kann nicht auf das Betriebssystem des Anwenders
zugreifen.
Auf diese Anwendung beschränkt sich die Vorlesung im Wesentlichen.
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
8
Prinzipien
Eigenschaften

Laufzeitumgebung auf dem Server: Als Server-Anwendung, Auslieferung von Web-Seiten und
anderen Informationen.
Browser
URL-Aufruf
Antwort
Web Server
URL-Aufruf (+ Parameter)
Antwort
lesen
Schnittstelle
Aufruf
JavaScriptProgramme

HTML-Seiten, Bilder,
JavaScript-Dateien,
CSS-Dateien …
(Dateisystem)
Diese Anwendung wird in der Vorlesung nicht behandelt.
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
9
Prinzipien
Eigenschaften

Laufzeitumgebung ist eine JVM zur Erweiterung oder Konfigurierung von Java-Programmen.
K1
K3
K2
Zugriff
Interpreter
Ereignis
Ausführung
JavaScript
Java-Objekte

GUI
Diese Anwendung wird in der Vorlesung nicht behandelt  kleines Beispiel in der Vorlesung
„Benutzungsoberflächen“.
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
10
Einstieg
Übersicht
Grafische
Oberflächen
Übersicht
Datenstrukturen
ADTs
Typinfo.,
I/O
Annotationen
JavaScript
Prinzipien
Holger Vogelsang
Layouts
Ereignisse
Datenstrukturen
in Java
Laufzeittypinfo.
Einstieg
Widgets
Grafikoperationen
Elementare
Datenstrukturen
Grafikwidgets
Effekte,
Animationen
Iteratoren
Hashtabellen
Bäume
Module
Private
Daten
DOMZugriffe
Offene
Punkte
Graphen
Ein-,
Ausgabe
Funktionen
Objekte und
Vererbung
Informatik 2 - Einführung in JavaScript
11
Einstieg
Das erste JavaScript-Programm


Als Laufzeitumgebung für die folgenden kleinen Beispiele eignet sich die Konsole des
Chrome- oder des Firefox-Browsers ganz gut:

Chrome: Tools  JavaScript-Konsole

Firefox: Entwickler-Werkzeuge  JavaScript-Umgebung zur Eingabe und Entwickler 
Browser-Konsole zur Ausgabe (vorher eventuell noch Firebug installieren)
Eingabe in die Konsole (entspricht ungefähr System.out.println in Java):
console.log('Hello World');

Ein- und Ausgabe (Chrome):
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
12
Einstieg
Das erste JavaScript-Programm



Ein- und Ausgabe (Firefox):
Es sind einfache und doppelte Anführungszeichen erlaubt.
console ist ein im Browser vorhandenes JavaScript-Objekt.
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
13
Einstieg
Das erste JavaScript-Programm



Ab jetzt: Beispiele in der WebStorm-IDE:

Node.js von http://nodejs.org/#download herunterladen und installieren

WebStorm von http://www.jetbrains.com/webstorm/download/ herunterladen (Lizenz
im Ilias), installieren

WebStorm starten und in File  Settings  JavaScript  Browser den Pfad auf
node.exe eintragen (falls nicht automatisch gefunden, je nach Betriebssystem hat die
Datei natürlich eine andere oder keine Endung).
Neues, leeres Projekt anlegen
Zum Projekt eine JavaScript-Datei Console.js (Name ist nicht wichtig) hinzufügen und
console.log('Hello World');
eintragen.
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
14
Einstieg
Das erste JavaScript-Programm

Ergebnis:
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
15
Einstieg
Das erste JavaScipt-Programm

Einbettung von JavaScript in eine HTML-Datei (EmbeddedJavaScript.html):
<!DOCTYPE html>
<html>
<head lang="de">
<meta charset="UTF-8">
<title>Hello World</title>
<script>
alert('Hello World');
</script>
</head>
<body>
<h1>Titelzeile</h1>
</body>
</html>


alert() ist eine vordefinierte Funktion in Browsern, die einen kleinen Dialog öffnet.
Der Dialog wird hier beim Laden der Seite und vor dem Anzeigen des Inhalts eingeblendet.
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
16
Einstieg
Das erste JavaScipt-Programm

Laden einer externen JavaScript-Datei (ExternalJavaScript.html):
function showMessage(message) {
<!DOCTYPE html>
alert(message);
<html>
}
<head lang="de">
<meta charset="UTF-8">
<title>Hello World</title>
<script type="text/javascript"
src="./js/External.js"></script>
Laden
</head>
der Datei
<body>
<h1>Hello World</h1>
<script>showMessage('Hello World')</script>
Aufruf
</body>
der Funktion
</html>


Das erste script-Tag erhält mit dem src-Attribut den Namen einer JavaScript-Datei.
Das zweite script-Tag enthält den Aufruf der geladenen Funktion. Die Funktion wird
aufgerufen, wenn der Teil der HTML-Seite geladen ist.
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
17
Einstieg
Datentypen



Es gibt in JavaScript nur sehr wenigen Datentypen:

object: Objekte, entsprechen ungefähr Maps in Java, zu denen Methoden und beliebige
Attribute hinzugefügt werden können. Auch Arrays sind Objekte.

string: Zeichenketten, entsprechen ungefähr der String-Klasse in Java.

number: Zahlen

boolean: Wahrheitswerte
Eine Variable wird ohne Typangabe angelegt: var year = 2000;
Typ einer Variablen zur Laufzeit auslesen, Operator typeof:
var year = 2000;
console.log(typeof year); // Ausgabe: number
year = 'Vogelsang';
console.log(typeof year); // Ausgabe: string


Das Schlüsselwort var kann weggelassen werden, sollte aber nicht: Ohne die Angabe wird
eine globale Variable erzeugt.
Tipp: Jede JavaScript-Datei mit 'use strict'; einleiten  gewisse alte Eigenschaften der
Sprache (z.B. Verzicht auf var) erzeugt Laufzeitfehler.
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
18
Einstieg
Datentypen: object


Objekte sind eigentlich nur Maps:

Attribute bestehen aus Schlüssel (Attributnamen) und Wert (Wert des Attributs)

Attributwerte können von einem beliebigen Typ sein  auch Funktionen!

Attribute lassen sich zur Laufzeit hinzufügen und mit delete entfernen.

Sie würden in Java einer Map<String, Object> entsprechen.
Erzeugen eines leeren Objektes (Konstruktoren usw. kommen später):
var obj1 = {};


obj1 ist eine Variable mit einer Referenz auf das Objekt.
Erzeugen eines Objektes mit Attributen:
var obj2 = {
lastname: 'Vogelsang',
firstname: 'Holger'
};

Zugriff auf die Attribute mit „.“ oder „[]“ (Angabe des Schlüssels = Attributname, Rückgabe
der Wert):
console.log(obj2.lastname);
console.log(obj2['lastname']);
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
19
Einstieg
Datentypen: object

Attribute können jederzeit überschrieben werden:
obj2.lastname = 'Gmeiner';

Es dürfen neue Attribute hinzugefügt werden:
obj2.age = 42;
obj2.role = function() { return 'Dozent'; };


Da Funktionen Objekte sind, dürfen sie einem Attribut als Wert zugewiesen werden. Auf
solche Funktionen wird später genauer eingegangen (und wie man das besser machen kann).
Entfernen eines Attributs aus einem Objekt:
delete obj2.age;
console.log(obj2.age); // Ausgabe: undefined

Typ eines Objekts:
console.log(typeof obj2); // Ausgabe: object
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
20
Einstieg
Datentypen: object (Array)

Erzeugen eines Arrays:
var values = [1, 2, 3, 4];

Typ eines Arrays:
console.log(typeof values); // Ausgabe: object

Zugriff auf Array-Elemente:
console.log(values[0]); // Ausgabe: 1
console.log(values); // Ausgabe: [ 1, 2, 3, 4 ]

Ändern der Array-Elemente, es müssen nicht alle Daten im Array denselben Typ haben:
values[ 2 ] = 'Name';
console.log(values); // Ausgabe: [ 1, 2, 'Name', 4 ]
Arrays sind im Gegensatz zu Java in ihrer Größe veränderlich.

Anhängen neuer Werte an das Ende des Arrays mit push:
values.push(42, 66);
console.log(values); // Ausgabe [ 1, 2, 'Name', 4, 42, 66 ]
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
21
Einstieg
Datentypen: object (Array)

Entfernen von Werten aus dem Array mit splice:
values.splice(1, 2); // an Position 1 werden 2 Elemente entfernt
console.log(values); // Ausgabe [ 1, 4, 42, 66 ]


Mit splice lassen sich auch Werte einfügen (siehe JavaScript-Referenz).
Länge eines Arrays:
var values = [1, 2, 3, 4];
console.log(values.length); // Ausgabe: 4

Die Länge kann vergrößert oder verkleinert werden:
values.length = 6;
console.log(values); // Ausgabe: [ 1, 2, 3, 4, ,
console.log(values[ 5 ]); // Ausgabe: undefined
values.length = 3;
console.log(values); // Ausgabe: [ 1, 2, 3 ]

]
Es darf auch über die Array-Grenzen hinaus geschrieben werden. Dabei wird das Array
automatisch vergrößert:
values = [1, 2, 3, 4];
values[ 8 ] = 8;
console.log(values); // Ausgabe: [ 1, 2, 3, 4, , , , , 8 ]
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
22
Einstieg
Datentypen: object (Array)

Es gibt weitere Methoden, z.B. shift (verschiebt alle Elemente um eines nach links):
values = [1, 2, 3, 4];
values.shift();
console.log(values); // Ausgabe (die 1 ist jetzt weg): [ 2, 3, 4 ]

Die JavaScript-Referenz sowie die Code-Vervollständig in z.B. WebStorm zeigen viele weitere
Methoden auf Arrays.
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
23
Einstieg
Datentypen: object (string)

Strings sind denen aus Java ähnlich.

Einfache Anführungszeichen (oft bevorzugte Variante): var name = 'Vogelsang';

Doppelte Anführungszeichen: var name = "Vogelsang";

Der Typ eines Strings ist string:
console.log(typeof name); // Ausgabe: string

Jedes Zeichen eines Strings ist wiederum ein String:
var first = name[ 0 ];
console.log(typeof first); // Ausgabe: string


Es gibt also kein einzelnes char wie in Java.
Strings lassen sich mit += und + verbinden  kann langsam sein, weil viele
Zwischenobjekte erzeugt werden. Besser, wenn die Strings im Array vorliegen:
var strings = ['a', 'b', 'c', 'd' ];
var result = strings.join('-'); // Alle verbinden, Trennzeichen ist '-'
console.log(result); // Ausgabe: a-b-c-d
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
24
Einstieg
Datentypen: object (string)

Die JavaScript-Referenz sowie die Code-Vervollständig in z.B. WebStorm zeigen viele weitere
Methoden auf Strings.
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
25
Einstieg
Datentypen: object (number)




Es gibt in JavaScript mit number nur einen Zahlentyp.
Er entspricht im Wesentlichen double in Java.
Beispiele:
var age = 22;
console.log(age);
console.log(typeof age);
// Ausgabe: 22
// Ausgabe: number
var price = 42.33;
console.log(price);
console.log(typeof price);
// Ausgabe: 42.33
// Ausgabe: number
console.log(age * price);
// Ausgabe: 931.26
Zwischen string und number kann manuell umgewandelt werden:
age = parseInt("42.33");
console.log(age);
console.log(typeof age);
// Ausgabe: 42
// Ausgabe: number
price = parseFloat("42.33");
console.log(price);
// Ausgabe: 42.33
console.log(typeof price);
// Ausgabe: number
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
26
Einstieg
Datentypen: object (number)



Eine Fließkommazahl kann gerundet werden, dabei darf die Anzahl der Nachkommastellen
angegeben werden:
price = 22.66;
price = price.toFixed();
console.log(price);
// Rundung in ganze Zahl
// Ausgabe: 23
price = 22.66;
price = price.toFixed(1);
console.log(price);
// Rundung auf eine Nachkommastelle
// Ausgabe: 22.7
Zahlen sind also immer Objekte!
Was passiert beim Rechnen, wenn Fehler auftreten?

Es gab bei der Einführung von JavaScript noch keine Exceptions.

Es werden Fehlerinformationen in der Variablen gespeichert.
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
27
Einstieg
Datentypen: object (number)

Beispiele:
var result = price / 0;
console.log(result);
console.log(typeof result);
result *= 10;
console.log(result);
result = 0 / 0;
console.log(result);
console.log(typeof result);
result /= (0 / 0);
console.log(result);

// Ausgabe: Infinity
// Ausgabe: number
// Ausgabe: Infinity
// Ausgabe: NaN (steht für Not a Number)
// Ausgabe: number
// Ausgabe: NaN
Weitere Mathe-Operationen sind über das Math-Objekt verfügbar.
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
28
Einstieg
Datentypen: object (boolean)

Für Wahrheitswerte gibt es den Datentyp boolean:
var dead = false;
console.log(dead);
// Ausgabe: false
console.log(typeof dead); // Ausgabe: boolean
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
29
Einstieg
Variable: Typen




Erinnerung:

Variablen werden keine festen Datentypen zugewiesen.

Variablen haben zur Laufzeit Typen, die sich ändern können.
Wie kann trotzdem mit Werkzeugunterstützung halbwegs sicher programmiert werden?
Lösung: Typhinweis im Kommentar, der von der IDE wie WebStorm, ausgewertet wird.
Beispiel in WebStorm:
Warnung

Einblendung unter dem Mauszeiger:

Aber das ist erlaubt und funktioniert!
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
30
Einstieg
Variable: Blöcke



In Java lebt eine Variable nur innerhalb des zugehörigen Blocks („zwischen den geschweiften
Klammern“).
In JavaScript begrenzen nur Funktionen die Lebensdauern von Variablen.
Beispiel:
for (var x = 0; x < 10; x++) {
console.log(x);
}
console.log("Nach der Schleife: " + x);


x ist nach Beendigung der Schleife noch sichtbar und hat den Wert 10.
Beispiel zu Funktionen:
function calc() {
var x = 0;
console.log(x);
}

x ist außerhalb der Funktion nicht mehr sichtbar.
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
31
Einstieg
Variable: Vergleiche


Es gibt zwei Vergleichsoperatoren:

==, !=: Test auf Gleichheit bzw. Ungleichheit, notfalls mit Hilfe von Konvertierungen
(„equals operator“)

===, !==: Gleichheit bzw. Ungleichheit ohne Konvertierung („strict equals operator“),
entspricht eher dem == bzw. != in Java, ist in JavaScript bevorzugt zu verwenden.

Objekte und Arrays werden über ihre Referenzen, nicht den Inhalt, vergleichen.
Beispiele:
1 == true
true
1 === true
false
1 == "1"
true
var obj1 = {}; false
var obj2 = {};
obj1 == obj2
Holger Vogelsang
1 === "1"
false
var obj1 = {}; false
var obj2 = {};
obj1 === obj2;
Informatik 2 - Einführung in JavaScript
32
Einstieg
Variable: Undefinierter Inhalt



In Java stellt der Compiler sicher, dass es keine Zugriffe auf nicht initialisierte Variable gibt
und dass alle Variablen, auf die zugegriffen wird, auch existieren.
In JavaScript gibt es keinen Compiler: Variable können beim Zugriff uninitialisiert sein.
Beispiel:
var name;
console.log(name); // Ausgabe: undefined
console.log(typeof name); // Ausgabe: undefined

Beispiel für den Test auf Initialisierung:
var name1;
console.log(typeof name1 === 'undefined'); // Ausgabe: true

Wie in Java dient null der gezielten Initialisierung mit „nichts“. Beispiel:
var name2 = null;
console.log(typeof name2 === 'undefined'); // Ausgabe: false
console.log(typeof name2); // Ausgabe: object (null ist vom Typ object)

Zugriff auf eine nicht vorhandene Variable:
console.log(name3); // Programmabbruch
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
33
Einstieg
Variable: Undefinierter Inhalt

Beispiel zum Zugriff auf eine nicht initialisierte bzw. nicht vorhandene Eigenschaft eines
Objektes:
var object = {
attr1: undefined
};
console.log(object.attr1); // Ausgabe: undefined
console.log(object.attr2); // Ausgabe: undefined

Tipp: Initialisieren Sie alle Variablen und Attribute während ihrer Deklaration. Es gibt keinen
Compiler, der die Initialisierung sicherstellt.
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
34
Einstieg
Kontrollstrukturen

Vergleich mit Java
Anweisung
Java
JavaScript
if
Bedingung muss ein
Boole‘scher Wert sein
Bedingung ist true für alles außer
false, undefined, null, 0, NaN, ""
switch
erlaubte Typen: ganzzahlige
Werte, String, Aufzählungen
wie in Java, Wert wird mit ===
vergleichen
?:
wie in Java
while,
do … while,
break, continue
wie in Java
for
ähnlich zu Java, Laufvariable vom
„Typ“ var ist auch außerhalb der
Schleife sichtbar
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
35
Einstieg
Kontrollstrukturen


Es gibt noch eine besondere Form der for-Schleife: for … in
Die Schleife iteriert über alle Properties eines Arrays oder Objektes. Beispiel:
// Objekt mit zwei Attributen
var object = {
attr1: 1,
attr2: 2
};
// Array mit vier Werten
var values = [1, 2, 3, 4];
// Durchlaufen aller Properties (Attribute) des Objektes
for (var p1 in object) {
console.log('Attribut ' + p1 + ' = ' + object[p1]);
}
// Durchlaufen aller Properties (Indizes) des Arrays
for (var p2 in values) {
console.log('Index ' + p2 + ' = ' + values[p2]);
}
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
36
Einstieg
Ausnahmen


Ausnahmen sehen denen in Java recht ähnlich. Ausnahme: Es gibt keine Klassen!
Eine Ausnahme ist ein Objekt. Beispiel:
try {
throw 'Eingabefehler';
// Oder besser: throw new Error('Eingabefehler');
}
catch (error) {
console.log('Fehler: ' + error);
}
finally {
console.log('Wie in Java immer aufgerufen');
}
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
37
Funktionen
Übersicht
Grafische
Oberflächen
Übersicht
Datenstrukturen
ADTs
Typinfo.,
I/O
Annotationen
JavaScript
Prinzipien
Holger Vogelsang
Layouts
Ereignisse
Datenstrukturen
in Java
Laufzeittypinfo.
Einstieg
Widgets
Grafikoperationen
Elementare
Datenstrukturen
Grafikwidgets
Effekte,
Animationen
Iteratoren
Hashtabellen
Bäume
Module
Private
Daten
DOMZugriffe
Offene
Punkte
Graphen
Ein-,
Ausgabe
Funktionen
Objekte und
Vererbung
Informatik 2 - Einführung in JavaScript
38
Funktionen
Einführung




Auch Funktionen sind Objekte, die Variablen zugewiesen werden können.
Sie „können“ wesentlich mehr als Methoden in Java oder Funktionen in C/C++.
Eine Funktion kann einen eigenen Namen und Übergabeparameternamen besitzen.
Beispiele ohne Parameter:
// Definition der Funktion print.
function print() {
console.log('Aufgerufen 1');
}
// Aufruf der Funktion print:
print(); // Ausgabe: Aufgerufen 1
// Definition der Variablen printer, die eine anonyme Funktion aufnimmt.
var printer = function() {
console.log('Aufgerufen 2');
};
// Aufruf der anonymen Funktion mit Hilfe der Variablen
printer(); // Ausgabe: Aufgerufen 2
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
39
Funktionen
Einführung

Da eine Funktion ein Objekt ist, lassen sich auf Funktions-Objekten Methoden aufrufen.
Beispiel:
// Definition der Funktion print.
var printer = function() {
console.log('Aufgerufen 2');
}
// Direkter Aufruf der Funktion:
printer();
// Aufruf über die call-Methode des Funktions-Objektes:
printer.call();
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
40
Funktionen
Einführung

Parameter und Rückgabewerte einer Funktion sind im Quellcode „typlos“:
function minSqr(x, y) {
return x < y ? x * x : y * y;
}
console.log(minSqr(2,3));

Da ein Aufrufer die Typen nicht erkennen kann, sollten sie immer im JsDoc-Kommentar in
geschweiften Klammern angegeben werden. So können IDEs wie WebStorm sie erkennen
und Prüfungen vornehmen.
/**
* Berechnet den Quadratwert des Minimums zweier Zahlen.
* @param {number} x Erste zu vergleichende Zahl.
* @param {number} y Zweite zu vergleichende Zahl.
* @returns {number} Das Minimum beider Argumente.
*/
function minSqr(x, y) {
return x < y ? x * x : y * y;
}
console.log(minSqr(2,3));
console.log(minSqr('aa', 'bb'));
Warnung von WebStorm
Optionale Parameter und variable Parameteranzahlen werden hier nicht betrachtet.
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
41
Funktionen
Höherer Ordnung


Da Funktionen Objekte sind, können sie als Parameter an andere Funktionen übergeben
werden.
Beispiel: Durchlaufen eines Arrays mit einer forEach-Schleife:
var values = [1, 2, 3, 4, 5];
values.forEach(function (value) {
console.log(value);
});

forEach erwartet eine Funktion als Parameter, vielleicht so besser erkennbar:
var logger = function(value) {
console.log(value);
};
values.forEach(logger);

Bereits von der Stream-API in Java bekannt!
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
42
Funktionen
Höherer Ordnung



Wozu das Ganze? Es geht doch auch prozedural mit Index-Zugriff.
Vorteil: Längere „Verkettung“ von Aufrufen wie bei der Stream-API in Java.
Beispiel zur Verkettung, Ausgabe nur der geraden Werte des Arrays values:
values.filter(function(value) {
return value % 2 == 0;
}).forEach(function(value) {
console.log(value);
});

Funktionen:

Die Funktion im filter-Argument liefert true, wenn der Wert im Ergebnis vorhanden
sein soll.

Die Funktion im forEach-Argument wird für jeden Wert, den der Filter durchgelassen
hat, aufgerufen.
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
43
Funktionen
Höherer Ordnung


Mächtiges Konzept der map- und reduce-Aufrufe bei Arrays:

map bildet jeden Wert auf einen neuen ab.

reduce erzeugt aus allen Werten des Arrays ein Ergebnis.
Beispiel zur Summierung der Quadratzahlen aller Arraywerte aus values:
var result = values.map(function(value) {
return value * value;
}).reduce(function(tempReducedValue, value) {
return tempReducedValue + value;
});
console.log('Summe der Quadratzahlen: ' + result);

Funktionen:

Die Funktion im map-Argument erhält als Argument in jedem Aufruf einen Wert des
Arrays und liefert als Ergebnis den neuen Wert zurück.

Die Funktion im reduce-Argument erhält als Werte das bisherige Zwischenergebnis
(tempReducedValue) sowie das von map berechnete neue Argument (value). reduce
liefert das neue Zwischenergebnis zurück.
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
44
Funktionen
Hoisting



JavaScript sortiert die Deklarationen der Variablen in einer Funktion um, so dass immer alle
Deklarationen am Anfang stehen („Hoisting“: an den Anfang der Funktion gehoben).
Die Initialisierungen erfolgen aber erst dort, wo sie auch im Quelltext stehen.
Beispiel:
function hoistingDemo() {
console.log(value); // Ausgabe: undefined
var value = 10;
console.log(value); // Ausgabe: 10
}
entspricht
hoistingDemo();


function hoistingDemo() {
var value;
console.log(value);
value = 10;
console.log(value);
}
hoistingDemo();
Der erste console.log-Aufruf links im Beispiel erzeugt keinen Fehler, da value schon
bekannt, aber nicht initialisiert ist.
Tipp: Alle Variablen immer am Anfang einer Funktion deklarieren.
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
45
Objekte und Vererbung
Übersicht
Grafische
Oberflächen
Übersicht
Datenstrukturen
ADTs
Typinfo.,
I/O
Annotationen
JavaScript
Prinzipien
Holger Vogelsang
Layouts
Ereignisse
Datenstrukturen
in Java
Laufzeittypinfo.
Einstieg
Widgets
Grafikoperationen
Elementare
Datenstrukturen
Grafikwidgets
Effekte,
Animationen
Iteratoren
Hashtabellen
Bäume
Module
Private
Daten
DOMZugriffe
Offene
Punkte
Graphen
Ein-,
Ausgabe
Funktionen
Objekte und
Vererbung
Informatik 2 - Einführung in JavaScript
46
Objekte und Vererbung
Einführung



Bisher wurden in der Vorlesung eigene Objekte direkt als Hash-Tabelle angelegt. Nachteile:

Es fehlte der Konstruktoraufruf.

Es können nicht mehrere Objekte eines Typs erzeugt werden.

Methoden werden (wie Attribute) einzelnen Objekten zugeordnet.
Besseres Vorgehen: Erzeugen von Objekten mit Hilfe von Konstruktorfunktionen.
Beispiel:
/**
* Erzeugt einen Kunden.
* @param {string} name
* @param {number} age
* @param {number} no
* @constructor
*/
function Customer(name, age, no) {
this.name = name;
this.age = age;
this.no = no;
}
var c1 = new Customer('Test', 42, -1);
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
47
Objekte und Vererbung
Einführung



Was passiert in dem Beispiel?

Es wird eine „normale“ Funktion definiert.

Es wird mit new ein Objekt erzeugt und dabei die Funktion aufgerufen.

Die Funktion initialisiert das Objekt.

Jetzt können beliebig viele Objekte mit den in der Konstruktorfunktion angegebenen
Attributen angelegt werden.
Wo sind die Methoden? Sie sollten nicht direkt in Attributen des Objekts gespeichert
werden:

Sie wären als Attribut in jedem erzeugten Objekt vorhanden.

Vererbung (kommt gleich) würde nicht gut funktionieren.
Jedes Objekt besitzt ein Attribut prototype. Es kann mit Hilfe der statischen Methoden
getPrototypeOf des Typs Object ausgelesen werden. Beispiel:
console.log(Object.getPrototypeOf(c1));

An diesem Attribut werden die Methoden gespeichert.
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
48
Objekte und Vererbung
Einführung

Gemeinsamer Prototyp aller durch eine Konstruktorfunktion erzeugten Objekte. Beispiel:
var c1 = new Customer('Test1', 42, -1);
var c2 = new Customer('Test2', 44, -1);
c1
c2

prototype
Zuordnung von „Methoden“ zu dem Customer-Typ, hier drei Getter:
Customer.prototype.getNo = function() {
return this.no;
};
Customer.prototype.getAge = function() {
return this.age;
};
Customer.prototype.getName = function() {
return this.name;
};
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
49
Objekte und Vererbung
Einführung

Aufruf der „Methoden“:
console.log(c1.getAge());
console.log(c1.getName());
console.log(c1.getNo());

Zusammenfassung:

Alle Attribute in der Konstruktorfunktion initialisieren.

Nicht vorhandene Attribute werden automatisch angelegt.

„Methoden“ außerhalb der Konstruktorfunktion dem Prototypen des Typs zuweisen.
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
50
Objekte und Vererbung
Einführung

Vollständiges Beispiel mit den Getter-Methoden (Getter sind hier eigentlich sinnlos, weil die
Attribute ohnehin öffentlich les- und schreibbar sind):
/**
* Erzeugt einen Kunden.
* @param {string} name
* @param {number} age
* @param {number} no
* @constructor
*/
function Customer(name, age, no) {
this.name = name;
this.age = age;
this.no = no;
}
/**
* Gibt die Kundennummer zurück.
* @returns {number} Kundennummer.
*/
Customer.prototype.getNo = function() {
return this.no;
};
Holger Vogelsang
@constructor ist ein Hinweis an die IDE
Zuweisung außerhalb der Funktion,
da ansonsten bei jedem neuen
Objekt erneut zugewiesen wird.
Informatik 2 - Einführung in JavaScript
51
Objekte und Vererbung
Einführung

Die beiden weiteren Methoden:
/**
* Gibt das Alter des Kunden zurück.
* @returns {number} Alter des Kunden.
*/
Customer.prototype.getAge = function() {
return this.age;
};
/**
* Gibt den Namen des Kunden zurück.
* @returns {string} Name des Kunden.
*/
Customer.prototype.getName = function() {
return this.name;
};
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
52
Objekte und Vererbung
Einführung

Da das Attribut prototype ein Objekt ist, können die Funktionen auch direkt in einem
neuen Objekt als Schlüssel-/ Wertepaare zugewiesen werden (Kommentare weggelassen):
Customer.prototype = {
getNo: function() {
return this.no;
},
getAge: function() {
return this.age;
},
getName: function() {
return this.name;
}
};
Holger Vogelsang
Schlüssel: Methodenname
Wert: Funktion
Informatik 2 - Einführung in JavaScript
53
Objekte und Vererbung
Vererbung


Zur Vererbung wird eine Besonderheit der Prototypen verwendet:

Einem Prototypen kann ein Vaterprototyp zugewiesen werden.

Wird eine Methode nicht im Prototypen des aufgerufenen Objektes gefunden, dann wird
sie im Vaterprototypen gesucht.

Ist die Methode auch nicht im Vaterprototypen vorhanden, dann wird dessen
Vaterprototyp durchsucht.

Das Ganze läuft bis zum Typ Object durch.

Hier: Vaterprototyp ist der Prototyp der Basisklasse.
Beispiel: Jeder Typ ist ein Object. Deswegen können direkt Methoden des Typs Object
aufgerufen werden.
var c1 = new Customer('Test', 42, -1);
console.log(c1.toString()); // Methode von Object

Die Methode toString wird nicht im Prototypen von Customer gefunden. Daher wird der
Vaterprototyp (hier der von Object) herangezogen.
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
54
Objekte und Vererbung
Vererbung

Prototypenverkettung:
Object.prototype
hat keinen Prototypen
Object.getPrototypOf(Object.getPrototypOf(c1))
Customer.prototype
Object.getPrototypOf(c1)
c1
var c1Proto
= Object.getPrototypeOf(c1);
var c1ParentProto
= Object.getPrototypeOf(c1Proto);
var c1ParentParentProto = Object.getPrototypeOf(c1ParentProto);
console.log((typeof c1Proto) + ', '
+ (c1Proto === Customer.prototype)); // Ausgabe: object, true
console.log((typeof c1ParentProto) + ', '
+ (c1ParentProto === Object.prototype)); // Ausgabe: object, true
console.log((typeof c1ParentParentProto) + ', '
+ c1ParentParentProto); // Ausgabe: object, null
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
55
Objekte und Vererbung
Vererbung



Wie soll Vererbung umgesetzt werden, ohne dass es Vererbung gibt?
Eine Funktion verbindet die Prototypen von Basistyp und abgeleitetem Typ!
Vereinfachte Implementierung der Funktion:
function _extends(Derived, Base) {
var _protoFunction = function() {};
_protoFunction.prototype = Base.prototype;
Derived.prototype = new _protoFunction();
}

Base.prototype
prototype
_protoFunction
prototype
Base
prototype
Derived
Erklärungen:

Derived ist der Name der Konstruktorfunktion für den abgeleiteten Typ.

Base ist der Name der Konstruktorfunktion für den Basistyp.

Der Prototyp des abgeleiteten Typs ist das neue Funktions-Objekt _protoFunction,
das seinerseits den Prototypen von Base als eigenen Prototypen besitzt (einem
Prototypen kann nicht direkt ein Prototyp zugewiesen werden).

Der Name der Funktion _extends startet hier mit einem Unterstrich, um zu zeigen, dass
sie nicht direkt zum eigentlichen Programm gehört („Bestandteil der Infrastruktur“).
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
56
Objekte und Vererbung
Vererbung

Mit halbwegs aktuellen Browsern (ab ECMAScript 5) kann Object.create verwendet
werden:
function _extends(Derived, Base) {
Derived.prototype = Object.create(Base.prototype);
}

Erklärung: Object.create erzeugt ein neues Objekt und weist ihm den Prototypen zu, der
als Parameter übergeben wurde.
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
57
Objekte und Vererbung
Vererbung

Beispielverwendung (Klassendarstellung in UML ist nicht ganz zutreffend  es gibt keine
Klassen), Basistyp:
/**
* Konstruktorfunktion des Basistyps
* @param val Im Objekt zu speichernder Wert.
* @constructor
*/
function Base(val) {
console.log('Base-Konstruktor: ' + val);
this.baseValue = val;
erzeugt und weist zu
}
/**
* Methode im Basistyp, gibt den intern
* gespeicherten Wert auf der Konsole aus.
*/
Base.prototype.print = function() {
console.log('Print in Base: ' + this.baseValue);
};
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
Base
+baseValue
+Base()
+print()
Derived
+value
+Derived()
+print()
58
Objekte und Vererbung
Vererbung

Beispielverwendung, abgeleiteter Typ:
/**
* Konstruktorfunktion des abgeleiteten Typs.
* @param val Im Objekt zu speichernder Wert.
* @constructor
*/
function Derived(val) {
// Aufruf des Basiskonstruktors
ruft auf
Base.call(this, val + 1);
console.log('Derived-Konstruktor: ' + val);
this.value = val;
erzeugt und weist zu
}
// Vererbungsbeziehung abbilden
_extends(Derived, Base);
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
Base
+baseValue
+Base()
+print()
Derived
+value
+Derived()
+print()
59
Objekte und Vererbung
Vererbung

Beispielverwendung, abgeleiteter Typ:
/**
* Methode im abgeleiteten Typ, gibt den intern
* gespeicherten Wert auf der Konsole aus.
* Wichtig: Die Methode darf erst nach Herstellen der
* Vererbungsbeziehung hinzugefügt werden, weil durch
* das Erstellen eines neuen Prototypen in der
* Vererbungsfunktion ansonsten diese Methode nicht
* mehr Derived zugeordnet wäre.
*/
Derived.prototype.print = function() {
console.log('Print in Derived: ' + this.value);
// Aufruf der print-Methode des Basis-Typs.
Base.prototype.print.call(this);
ruft auf
};
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
Base
+baseValue
+Base()
+print()
Derived
+value
+Derived()
+print()
60
Objekte und Vererbung
Vererbung

WebStorm erkennt die Vererbung im Beispiel:
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
61
Objekte und Vererbung
Vererbung

Vergleich mit Java:

Das Überschreiben von Methoden ist problemlos möglich.

Das Überladen wird nicht unterstützt, da der Methodenname der eindeutige Schlüssel
im Objekt ist. Überladen kann recht unelegant nachgebaut werden  soll hier nicht
besprochen werden.

Schnittstellen, Aufzähltypen und statische Methoden sowie statische Attribute können
nachgebaut werden  soll hier nicht betrachtet werden.

Bisher sind alle Daten und Methoden öffentlich, private werden gleich behandelt  ist
etwas komplizierter.

Standard-Methoden ähnlich zu equals und hashCode existieren nicht.
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
62
Module
Übersicht
Grafische
Oberflächen
Übersicht
Datenstrukturen
ADTs
Typinfo.,
I/O
Annotationen
JavaScript
Prinzipien
Holger Vogelsang
Layouts
Ereignisse
Datenstrukturen
in Java
Laufzeittypinfo.
Einstieg
Widgets
Grafikoperationen
Elementare
Datenstrukturen
Grafikwidgets
Effekte,
Animationen
Iteratoren
Hashtabellen
Bäume
Module
Private
Daten
DOMZugriffe
Offene
Punkte
Graphen
Ein-,
Ausgabe
Funktionen
Objekte und
Vererbung
Informatik 2 - Einführung in JavaScript
63
Module
Einführung





In Java existieren Pakete zur sauberen Modularisierung.
JavaScript kennt so ein Konzept nicht, allerdings kann es mit Funktionen und Objekten
nachgebaut werden.
Grundidee Closure:

Funktionen werden ineinander geschachtelt.

Innere Funktionen können auch dann auf die Daten der äußeren zugreifen, wenn diese
bereits beendet wurden.
Grundidee Namensraum:

Ein Namensraum ist ein Objekt, in das Funktionen und Objekte eingefügt werden.

Namensräume haben denselben Aufbau wie Pakete in Java.
Die Erzeugung der Daten erfolgt in einer anonymen, sofort ausgeführten Funktion. Syntax:
(function() {
// Mache etwas, der Inhalt ist privat
})();
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
64
Module
Definition

Beispiel für den Namensraum de.hska.iwii:
/**
* Definition der Namensräume mit Hilfe von Objekten.
*/
var de = {};
de.hska = {};
de.hska.iwii = {};

Es werden drei Objekte erzeugt:

de im globalen Namensraum.

hska innerhalb des Objekts de.

iwii innerhalb des Objekts de.hska.
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
65
Module
Definition




Die Zuweisung von Objekten und Funktionen erfolgt an die Namensraumobjekte.
Die Erzeugung und Zuweisung erfolgt innerhalb einer Funktion, damit deren Inhalt nicht
außerhalb der Funktion sichtbar ist.
Die Funktion ist anonym und wird sofort ausgeführt. Sie erhält als Parameter das
Namensraum-Objekt, zu dem die Daten hinzugefügt werden sollen.
Beispiel für Konfigurationsdaten:
/**
* Hinzufügen von Objekten zu einem Namensraum.
* Alle Daten innerhalb dieser sofort ausgeführten
* Funktion sind privat.
* @param modul Referenz auf das Namensraum-Objekt
*/
(function(modul) {
var server = {
name: 'www.hs-karlsruhe.de', port: 80
};
// Zuweisung an den Namensraum.
modul.HSServer = server;
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
66
Module
Definition

Und noch ein Funktionsobjekt mit Zugriffsmethoden zum Namensraum hinzufügen:
// Konstruktorfunktion sowie weitere Methoden.
var cust = function(name, age, no) {
this.name = name;
this.age = age;
this.no = no;
};
cust.prototype.getNo = function() {
return this.no;
};
cust.prototype.getAge = function() {
return this.age;
};
// Zuweisung an den Namensraum.
modul.Customer = cust;
})(de.hska.iwii); // Referenz auf den Namensraum
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
67
Module
Verwendung

Verwendung des Namensraums:
var server = de.hska.iwii.HSServer;
console.log(server.name);
var cust1 = new de.hska.iwii.Customer('Vogelsang', -1, 42);
console.log(cust1.getNo());


Auf die innerhalb der anonymen Funktion erzeugten Daten kann nicht direkt zugegriffen
werden, weil eine Funktion einen eigenen Namensraum bildet.
Eine direkte import-Anweisung wie in Java für Pakete gibt es nicht. Ausweg:

Es kann ein Namensraum-Objekt als Parameter an eine Funktion übergeben werden
(siehe Beispiel oben für die anonyme Funktion).

Dann kann über diesen Parameter direkt auf den Inhalt des Namensraums zugegriffen
werden.
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
68
Private Daten
Übersicht
Grafische
Oberflächen
Übersicht
Datenstrukturen
ADTs
Typinfo.,
I/O
Annotationen
JavaScript
Prinzipien
Holger Vogelsang
Layouts
Ereignisse
Datenstrukturen
in Java
Laufzeittypinfo.
Einstieg
Widgets
Grafikoperationen
Elementare
Datenstrukturen
Grafikwidgets
Effekte,
Animationen
Iteratoren
Hashtabellen
Bäume
Module
Private
Daten
DOMZugriffe
Offene
Punkte
Graphen
Ein-,
Ausgabe
Funktionen
Objekte und
Vererbung
Informatik 2 - Einführung in JavaScript
69
Private Daten
Kapselung



Bisher waren alle Daten öffentlich zugreifbar.
JavaScript kennt kein Schlüsselwort „private“. Aber die Kapselung kann mit Hilfe von
Funktionen erreicht werden.

Die privaten Daten sind lokale Variablen im Konstruktor.

Die privaten Funktionen werden im Konstruktor definiert. Sie dürfen auf die lokalen
Variablen des Konstruktors zugreifen („Closure“), auch wenn dieser beendet ist.
Beispiel:
function Customer(name, age, no) {
this.name = name;
this.age = age;
this.no = no;
// Lokale Variablen im Konstruktor, werden eigentlich
// bei Beendigung des Konstruktors gelöscht.
var secret = this.no * 2;
// Die Definition ist sinnvoll, da this in privaten Methoden nicht
// sichtbar ist.
var that = this;
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
70
Private Daten
Kapselung
// Private Methode (Funktion innerhalb des Konstruktors).
// Sie darf auf die lokalen Daten des Konstruktors zugreifen.
// Die lokalen Daten bleiben auch nach Beendigung des
// Konstruktoraufrufs erhalten (Closure).
function getSecretPrivate() {
return secret;
}
}


// Damit die private Methode auch außerhalb des
// Konstruktors verwendet werden kann, wird sie
// am Objekt registriert.
this.getSecret = function() {
return getSecretPrivate();
};
Auf die private Methode sowie die privaten Daten kann nicht von außerhalb des Objektes
zugegriffen werden.
Noch besserer Ansatz: Modulidee verwenden  soll hier nicht besprochen werden.
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
71
DOM-Zugriffe
Übersicht
Grafische
Oberflächen
Übersicht
Datenstrukturen
ADTs
Typinfo.,
I/O
Annotationen
JavaScript
Prinzipien
Holger Vogelsang
Layouts
Ereignisse
Datenstrukturen
in Java
Laufzeittypinfo.
Einstieg
Widgets
Grafikoperationen
Elementare
Datenstrukturen
Grafikwidgets
Effekte,
Animationen
Iteratoren
Hashtabellen
Bäume
Module
Private
Daten
DOMZugriffe
Offene
Punkte
Graphen
Ein-,
Ausgabe
Funktionen
Objekte und
Vererbung
Informatik 2 - Einführung in JavaScript
72
DOM-Zugriffe
Übersicht


Web-Seiten werden intern
im Browser durch ein
Modell, das Document
Object Model (DOM),
repräsentiert.
Der Baum kann zur Laufzeit
durch JavaScriptFunktionen verändert
werden.
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
73
DOM-Zugriffe
Auslesen des DOMs

Wie erfolgt der Zugriff auf das DOM?

document ist eine globale Referenz auf das komplette Dokument.

document besitzt Methoden zum Auslesen, Traversieren und Ändern des DOMs.
Beispiele:
- getElementById(): Sucht nach einem Tag, das eine bestimmte ID besitzt. Das
Ergebnis ist das gefundene Element oder null.
- getElementsByTagName(): Sucht nach allen Tags eines Typs (z.B. h1). Das
Ergebnis ist ein Array aller gefundenen Elemente.
- getElementsByClassName(): Sucht alle Elemente, die eine bestimmte CSS-Klasse
besitzen. Das Ergebnis ist ein Array aller gefundenen Elemente.
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
74
DOM-Zugriffe
Auslesen des DOMs

Beispiel, HTML-Seite:
<!DOCTYPE html>
<html>
<head lang="de">
<meta charset="UTF-8">
<title>DOM-Zugriffe (Auslesen)</title>
<script type="text/javascript" src="./js/Dom1.js"></script>
</head>
<body onload="find('title', 'contents')">
<h1 id="title">Titelzeile</h1>
<div id="div1" class="contents">DIV1</div>
<div id="div2" class="contents">DIV2</div>
</body>
</html>

onload: Sobald die Seite komplett geladen ist, wird dieses Ereignis vom Browser ausgelöst
und die angegebene Funktion aufgerufen.
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
75
DOM-Zugriffe
Auslesen des DOMs

Zugehörige JavaScript-Datei:
function find(id, className) {
var el = document.getElementById(id);
console.log(el);
el = document.getElementsByClassName(className);
for (var index = 0; index < el.length; index++) {
console.log(el.item(index));
}
}

Konsolenausgabe im Firefox:
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
76
DOM-Zugriffe
Ändern des DOMs


Auch Schreibzugriffe auf das DOM sind möglich:

Es gibt Attribute und Methoden, die auf allen Knoten des DOM definiert sind (z.B. id,
className, title).

Es gibt für die unterschiedlichen Knoten-Typen (HTML-Tags) weitere, individuelle
Attribute und Methoden (z.B. href für a-Tags <a>).

Das Attribut innerHTML enthält beispielsweise den HTML-Code des Inhalts eines Tags.
Beispiel zu innerHTML:
<!DOCTYPE html>
<html>
<head lang="de">
<meta charset="UTF-8">
<title>DOM-Zugriffe (Modifikation)</title>
<script type="text/javascript" src="./js/Dom2.js"></script>
</head>
<body onload="modify('contents')">
<h1>Titelzeile</h1>
<div id="contents"></div>
</body>
</html>
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
77
DOM-Zugriffe
Ändern des DOMs

Zugehörige JavaScript-Datei (fügt eine Tabelle in das div-Tag mit der ID contents ein):
function modify(elementId) {
var el = document.getElementById(elementId);
var innerHTML = '<table><tbody>';
var cnt = 0;
for (var row = 0; row < 4; row++) {
innerHTML += '<tr style=\'background-color: #0000C0; color: white;\'>';
for (var col = 0; col < 3; col++) {
innerHTML += '<td style=\'padding: 4px; text-align: right;\'>' + ++cnt + '</td>';
}
innerHTML += '</tr>';
}

}
innerHTML += '</tbody></table>';
el.innerHTML = innerHTML;
Die Tabellenzeilen werden noch blau eingefärbt.
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
eingefügt
78
DOM-Zugriffe
Ereignisbehandlung



Eine DOM-Dokumentation befindet sich z.B. unter https://developer.mozilla.org/enUS/docs/Web/API/Document_Object_Model, http://www.w3schools.com/jsref/ und
http://wiki.selfhtml.org/wiki/JavaScript/Objekte.
Ein wichtiges Konzept bei der Arbeit im Browser sind Ereignisse, durch die JavaScriptFunktionen aufgerufen werden, kleine Auswahl:

onload am body-Tag: Wenn das Dokument fertig geladen wurde.

onclick: Wenn der Anwender auf ein Element im Baum geklickt hat.

onresize: Wenn sich die Größe (Breite oder Höhe) des Dokument z.B. durch Verändern
der Fenstergröße geändert hat.
Werden Daten vom Server nachgeladen, dann geschieht das auch asynchron:

Es wird eine Anfrage (Request) an den Server abgesetzt und eine Funktion angegeben,
die bei Ereignissen aufgerufen werden soll.

Tritt ein Ereignis ein (Antwort vom Server erhalten, Fehler, …), dann wird die registrierte
Funktion aufgerufen.

Bei synchronem (also wartendem Zugriff) wäre der Browser ansonsten solange blockiert.
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
79
DOM-Zugriffe
Ereignisbehandlung

Beispiel zur zeitgesteuerten Durchführung von Aktionen (setInterval ruft alle x Sekunden
eine parameterlose Funktion auf):
<!DOCTYPE html>
<html>
<head lang="de">
<meta charset="UTF-8">
<title>DOM-Zugriffe (Zeitgesteuert)</title>
<script type="text/javascript" src="./js/Dom3.js"></script>
</head>
<body onload="setInterval(function(){modify('contents');}, 1000)">
<h1>Titelzeile</h1>
<div id="contents">
Huhu
</div>
</body>
</html>
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
80
DOM-Zugriffe
Ereignisbehandlung

Beispiel (JavaScript-Datei, setzt die Hintergrundfarbe des angegebenen Elements zyklisch
neu):
var colors = ['lightblue', 'silver', 'lightgreen'];
var colorIndex = 0;
function modify(elementId) {
var el = document.getElementById(elementId);
}

if (colorIndex == colors.length) {
colorIndex = 0;
}
el.setAttribute('style', 'background-color: ' + colors[ colorIndex++ ] + ';');
console.log(el.getAttribute('style'));
Es kann noch mehr mit dem DOM „angestellt“ werden  nicht Bestandteil der Vorlesung.
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
81
DOM-Zugriffe
Ausblick

Ist das nicht sehr mühsam? Wie sieht es mit Browserabhängigkeiten aus? Bibliotheken
vereinfachen die Arbeit, Auswahl:

jQuery: http://jquery.com/

Bootstrap: http://getbootstrap.com/

AngularJS: https://angularjs.org/
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
82
Ende
Holger Vogelsang
Informatik 2 - Einführung in JavaScript
83
Herunterladen