Web-Techniken Einführung in JavaScript Prof. Dr. Axel Böttcher Winter 2012/13 15. September 2012
Ausführung von JavaScript Variante 1: Ausführung im Browser durch direktes Einbetten: 1 <html> 2 <head> 3 < s c r i p t t y p e=" text / javascript "> 4 a l e r t ( " Hello World " ) ; 5 </ s c r i p t> 6 </ head> 7 8 <body> 9...... 10 </ body> 11 </ html>
Ausführung von JavaScript Variante 2: Ausführung im Browser durch Einbetten als Script: myscript.js 1 a l e r t ( H e l l o World ) ; 1 <html> 2 <head> 3 < s c r i p t t y p e=" text / javascript " s r c=" path / myscript.js"> 4 </ s c r i p t> 5 </ head> 6 <body> 7.... 8 </ body> 9 </ html>
Ausführung von JavaScript Variante 3: Ausführung mit nodejs etwa auch in cloud9 (www.c9.io) node myscript.js Achtung: hier haben Sie nicht das DOM des Browsers zur Verfügung, also: 1 c o n s o l e. l o g ( H e l l o World ) ; Die Konsole gibt es allerdings auch im Firefox über die Firebug Tools
Ausführung des Codes (Varianten 1 und 2) Code, der nicht in Funktionen gekapselt ist, wird direkt beim Laden ausgeführt. Der Seiteninhalt (DOM) kann erst nach vollständigem Laden manipuliert werden. 1 window. onload = f u n c t i o n ( ) { 2 // Initialisierungscode 3...... 4 } Das bringt uns schon direkt zu den Event-Listenern ( Observer-Pattern).
Das globale Objekt Im Browser gibt es das globale Objekt window. (bzw. global in nodejs) Alle Variablen, die innerhalb von Funktionen nicht mit dem Schlüsselwort var deklariert sind, werden Attribut des globalen Objekts!
Datentypen Jacascript ist dynamisch typisiert, d.h. dass sich der Typ einer Variablen aus dem Typ des ihrzugewiesenen Wertes ergibt. Die primitiven Typen sind number (hat Methoden, aber ist immutable) string (hat Methoden, aber ist immutable) boolean (hat Methoden, aber ist immutable) undefined null ( null ist ein Objekt) Daneben kennt die Sprache Objekte (unter die auch die Arrays sowie die Funktionen fallen!).
Semicolon Insertion Ein Semikolon ist optional (wird aber automatisch eingefügt) am Zeilenende (Ausnahme: leere Anweisung und Kopf einer for-schleife) vor einer } am Ende des Programms Dies ist insbesondere deshalb ungünstig, weil durch Semikolon aus jedem beliebigen zulässigen Ausdruck eine Ausdrucksanweisung entsteht: 1 r e t u r n 2 4 2 ;
JsLint Sehr hilfreiches Tool zum Überwachen der Codequalität. Online unter http://www.jslint.com/ Kommandozeilentool bei http://code.google.com/p/jslint4java/ Als Java library verfügbar, somit in JUnit ausführbar: 1 @Test 2 p u b l i c v o i d t e s t W i t h J s L i n t ( ) { 3.. 4 J S L i n t B u i l d e r b u i l d e r = new J S L i n t B u i l d e r ( ) ; 5 J S L i n t j s L i n t = b u i l d e r. f r o m D e f a u l t ( ) ; 6 J S L i n t R e s u l t l i n t = 7 j s L i n t. l i n t ( filename, b u f f e r e d R e a d e r O f J S S o u r c e C o d e ) ; 8 L i s t <I s s u e > i s s u e s = l i n t. g e t I s s u e s ( ) ; 9 a s s e r t E q u a l s ( J S L i n t i s s u e s!, 0, i s s u e s. s i z e ( ) ) ; 10 }
Funktionen Funktionen sind der Kern der Sprache. 1st class citizens Lokale Variablen werden definiert mit Schlüsselwort var, ohne Typangabe. Sie können überall in einer Funktion definiert werden. Der Gültigkeitsbereich jeder Variablen ist die komplette Funktion (nicht nur der Block, in dem die Variable definiert ist.) So genanntes Hoisting (Hochziehen). Formalparameter können deklariert werden. Nicht explizit übergebene Aktualparameter sind undefined Alle Aktualparameter sind in einem Array arguments verfügbar.
Closures Der Kontext einer inneren Funktion enthält den Kontext der umgebenden (äußeren) Funktion (Ausnahme: this der umgebenden Funktion) selbst dann, wenn die äußere Funktion bereits durch return beendet wurde. Die Closure ist privat (von außen nicht sichtbar)!
Beispiel (von D. Crockford) 1 f u n c t i o n i n i t ( ) { 2 f a d e ( button ) ; 3 } 4 5 f u n c t i o n f a d e ( i d ) { 6 v a r e l e m e n t = document. g e t E l e m e n t B y I d ( i d ), 7 l e v e l = 1 ; 8 f u n c t i o n s t e p ( ) { 9 v a r h = l e v e l. t o S t r i n g ( 1 6 ) ; 10 e l e m e n t. s t y l e. b a c k g r o u n d C o l o r = 11 #FFFF + h + h ; 12 i f ( l e v e l < 15) { 13 l e v e l ++; 14 settimeout ( step, 1 0 0 ) ; 15 } 16 } 17 settimeout ( step, 1 0 0 ) ; 18 }
Objekte Objekte können einfach als Literale hingeschrieben werden: 1 v a r r a t i o n a l = { 2 num : u n d e f i n e d, 3 denom : u n d e f i n e d, 4 r e d u c e : f u n c t i o n ( ) { 5 v a r r ; 6 v a r n = t h i s. num ; 7 v a r d = t h i s. denom ; 8 f o r ( r = n % d ; r!== 0 ; r = n % d ){ 9 n = d ; 10 d = r ; 11 } 12 t h i s. num /= d ; 13 t h i s. denom /= d ; 14 } 15 } ;
Zugriff auf die Attribute Ähnlich zu Objekten in Java. Aber auch Ähnlichkeit zur Array-Syntax von Java. 1 r a t i o n a l. num = 1 5 ; 2 r a t i o n a l [ denom ] = 1 0 ; 3 r a t i o n a l. r e d u c e ( ) ; Es geht noch wilder: 1 v a r someobject = { 2 1 : u n d e f i n e d ; 3 } 4 someobject [ 1 ] = 4 2 ;
Erzeugung von Objekten Hinschreiben als Objektliteral mittels Object. create mittels new Mischformen, Factories etc.
Prototypen Es gibt keine Klassen in JavaScript, nur Objekte und Funktionen. Erzeugen von Objekten und Vererbung erfolgt durch Prototypen. Prototypische Objekterzeugung ( Klonen): 1 v a r b = O b j e c t. c r e a t e ( r a t i o n a l ) ; // Klon 2 O b j e c t. g e t P r o t o t y p e O f ( b ) ; // --> rational Eigentlich hätten wir gerne sowas wie einen Konstruktor: 1 v a r b = new R a t i o n a l ( 1 5, 1 0 ) ;
Pseudoklassisch 1 f u n c t i o n R a t i o n a l (num, denom ){ 2 t h i s. num = num ; 3 t h i s. denom = denom ; 4 } 5 6 R a t i o n a l. p r o t o t y p e. r e d u c e = f u n c t i o n ( ) { 7 v a r r ; 8 v a r n = t h i s. num ; 9 v a r d = t h i s. denom ; 10 f o r ( r = n % d ; r!== 0 ; r = n % d ){ 11 n = d ; 12 d = r ; 13 } 14 t h i s. num /= d ; 15 t h i s. denom /= d ; 16 } ; 17 18 v a r b = new R a t i o n a l ( 1 5, 1 0 ) ; 19 b. r e d u c e ( ) ;
Ohne umständlichen Prototype unter Ausnutzung der Closure 1 v a r r a t i o n a l = f u n c t i o n (num, denom ){ 2 r e t u r n { 3 r e d u c e : f u n c t i o n ( ) { 4 v a r r ; 5 v a r n = num ; 6 v a r d = denom ; 7 f o r ( r = n % d ; r!== 0 ; r = n % d ){ 8 n = d ; 9 d = r ; 10 } 11 num /= d ; 12 denom /= d ; 13 }, 14 getnum : f u n c t i o n ( ) { r e t u r n num ; }, 15 getdenom : f u n c t i o n ( ) { r e t u r n denom ; } 16 } ; 17 } ; 18 19 v a r r 1 = r a t i o n a l ( 1 5, 1 0 ) ; 20 r 1. r e d u c e ( ) ; 21 c o n s o l e. l o g ( r 1. getnum ( ) ) ;
Fortsetzung... 1 c o n s o l e. l o g ( O b j e c t. g e t P r o t o t y p e O f ( r 1 ) ) ; 2 c o n s o l e. l o g ( O b j e c t. getownpropertynames ( r 1 ) ) ; Ausgabe: {} [ getnum, getdenom, reduce ] In der Closure lassen sich Methoden verstecken ( private)
Vererbung durch einfaches Hinzufügen von Methoden 1 v a r f o o = f u n c t i o n ( myname ){ 2 r e t u r n { 3 name : myname, 4 t o S t r i n g : f u n c t i o n ( ) { r e t u r n t h i s. name ; } 5 } ; 6 } ; 7 8 v a r bar = f u n c t i o n ( ) { 9 v a r t h a t = f o o ( bar ) ; 10 t h a t. setname = f u n c t i o n ( newname ){ 11 t h a t. name = newname ; 12 } ; 13 r e t u r n t h a t ; 14 } ;
JQuery Hilfreiche und sehr weit verbreitete Library, um mit dem DOM zu arbeiten.
Selektoren Kern ist die globale Funktion jquery kurz $. Aufruf mit Selektor als Parameter liefert Array mit JQuery-Wrapper-Objekten, die bequem manipuliert werden können. 1 $ (. s o m e c l a s s ). h i d e ( ) ; // iteriert implizit Return-Wert ist wieder die Collection = Operationen sind kaskadierbar
Event-Listener 1 < s c r i p t t y p e= t e x t / j a v a s c r i p t > 2 window. onload = f u n c t i o n ( ) {... } 3 </ s c r i p t >
Asynchronous Javascript and XML (AJAX) Statt XML ist heute JSON verbreiteter.
Same Origin Policy Longrightarrow Starten Sie Seiten mit aktiven (JavaScript) Inhalten nicht per Doppelklick, sondern laden Sie diese stets über den/einen Server.