LinuxUser Programmieren (Vorschau)
Sie wollen auch ein ePaper? Erhöhen Sie die Reichweite Ihrer Titel.
YUMPU macht aus Druck-PDFs automatisch weboptimierte ePaper, die Google liebt.
Javascript<br />
SCHWERPUNKT<br />
nierte Funktionen (innere Funktionen)<br />
stets auf Variablen der sie<br />
umgebenden Funktion zugreifen,<br />
die äußere Funktion aber natürlich<br />
nicht auf die der inneren: Das<br />
würde zu einem einzigen durchgängigen<br />
Variablen-Gültigkeitsbereich<br />
führen.<br />
Die beiden Aufrufe von greeter1.<br />
sayHello() und greeter2.sayHello()<br />
zeigen, dass der Wert aus dem Parameter<br />
who in toGreet gespeichert<br />
bleibt, obwohl die Funktion Greeter<br />
schon gelaufen ist.<br />
Das liegt daran, dass an Variablen<br />
gebundene Funktion in Javascript<br />
sozusagen ihre Laufzeitumgebung<br />
mit einpacken. Konkret<br />
heißt das: Alle Variablen aus der<br />
Umgebung von sayHello, auf die<br />
die Funktion zugreift, verweilen<br />
im Speicher, solange die Funktion<br />
selbst an eine Variable gebunden<br />
bleibt. Hierfür zeichnen greeter1<br />
und greeter2 verantwortlich, die<br />
sayHello() als Attribut enthalten.<br />
Diese Technik nennt sich Closure<br />
(Einschluss).<br />
Das Prinzip des Closure ist an<br />
sich einfach: Der Javascript-Interpreter<br />
geht den Code vor dem<br />
Ausführen einmal durch und notiert<br />
sich, welche Stellen des Programms<br />
auf welche Variablen zugreifen.<br />
Bei der Frage, wie lange<br />
Variablen im Speicher bleiben,<br />
gilt die Regel: Alles, was noch gebraucht<br />
wird, bleibt im Speicher.<br />
Eltern und Kind<br />
Nun bleibt nur noch das Schlüsselwort<br />
new zu erläutern, das aus<br />
der Funktionsdefinition Greeter<br />
die zwei Objektinstanzen greeter1<br />
und greeter2 macht, die verschiedene<br />
Werte für toGreet beherbergen.<br />
new Funktion() bewirkt zweierlei:<br />
Es erzeugt ein Objekt und<br />
es führt function() aus.<br />
Dabei sind function() und das<br />
Objekt identisch. Die Funktion<br />
verändert sich also bei der Attributzuweisung<br />
this.Attributname<br />
selbst. Nach dem Ausführen der<br />
Funktion bindet der Aufruf new<br />
das Funktionsobjekt (das mit der<br />
Funktion identische Objekt) an<br />
die Variable greeter1 oder greeter2,<br />
gerade so, als würde die Funktion<br />
mit return this enden.<br />
Objektinstanzen aus einer gemeinsamen<br />
Definition entstehen<br />
also in Javascript durch den Aufruf<br />
new Funktion(Parameter). Innerhalb<br />
der in Funktionsvariable gespeicherten<br />
Funktion verhalten<br />
sich Variablen wie private Datenfelder<br />
oder – wenn ihr Inhalt eine<br />
Funktion ist – wie private Methoden.<br />
Dagegen erzeugt this.Attributname<br />
öffentlich zugängliche<br />
Attribute oder Methoden.<br />
Schwieriges Erbe<br />
Stellen Sie sich vor, Sie haben<br />
eine Klasse mit fünf Methoden<br />
definiert und möchten nun eine<br />
neue Klasse bilden, die vier davon<br />
übernimmt, die fünfte aber verändert:<br />
Ein klarer Fall für Vererbung.<br />
Wie das in Javascript geht,<br />
demonstriert Listing 3. Darin erhält<br />
die von Greeter() abgeleitete<br />
Klasse den bairischen Gruß.<br />
Der Code definiert die zwei<br />
Funktionen Greeter und extended-<br />
Greeter. In Greeter haben wir im<br />
Vergleich zur früheren Version<br />
toGreet in ein öffentliches Attribut<br />
verwandelt. extendedGreeter()<br />
definiert eine Methode bavarian-<br />
Hello(). Sie greift dabei auf das in<br />
Greeter definierte Attribut toGreet<br />
zu. Das funktioniert, weil die erste<br />
Zeile nach den Funktionsdefinitionen<br />
Greeter und extendedGreeter<br />
kombiniert. Diese Zeile bindet<br />
eine Instanz von Greeter an das<br />
prototype-Attribut der Definition<br />
von extendedGreeter.<br />
Alle Javascript-Objekte enthalten<br />
ohne explizite Definition ein<br />
prototype-Attribut mit fester Aufgabe:<br />
Alle mit new extendedGreeter()<br />
erzeugten Instanzen erben<br />
die Attribute des an prototype gebundenen<br />
Objekts.<br />
Allerdings gilt dies nur für die<br />
öffentlichen, mit this.Attributname<br />
definierten Attribute. Darum gilt<br />
es die Klasse Greeter zu verändern,<br />
um diese zu erweitern. Abbildung<br />
D zeigt einen Object-<br />
Dump der Firebug-Konsole mit<br />
der geerbten Methode sayHello()<br />
sowie dem neu hinzugefügten<br />
bava rianHello().<br />
Kollateralschaden<br />
Ein Vererben privater Attribute<br />
funktioniert in Javascript nur<br />
über Umwege – mit unterschiedlichen<br />
Auswirkungen auf die Performance<br />
([9],[10]). Dass keine<br />
Kombination der beiden mächtigsten<br />
Features – dem Erzeugen<br />
von Objektinstanzen mit new und<br />
einer Closure sowie dem Vererben<br />
auf Basis des Prototype-Attributs<br />
– möglich ist, hat der Sprache viel<br />
Kritik eingebracht. Die Objektorientierung<br />
in Javascript wirkt unausgegoren.<br />
Sie ist, wie viele Webstandards,<br />
vom Browser-Krieg<br />
zwischen Netscape und Microsoft<br />
gezeichnet. (agr) n<br />
D Ein Dump des<br />
Objekts greeter3 in<br />
der Firebug-Konsole<br />
(zweite, grüne Zeile<br />
links) zeigt, dass das<br />
Vererben aus dem Beispiel<br />
funktioniert: Das<br />
Objekt enthält das<br />
Attribut toGreet sowie<br />
die beiden Methoden<br />
bavarianHello() und<br />
sayHello().<br />
INFO<br />
[1] Programmiersprachen-Shootout: http:// shootout. alioth. debian. org/ u32/ which-p<br />
rogramming-languages-are-fastest. php<br />
[2] Javascript-Überblick: http:// www. w3schools. com/ js/ default. asp<br />
[3] JQuery: http:// jquery. com<br />
[4] Cascading Style Sheets (CSS):<br />
http:// de. wikipedia. org/ wiki/ Cascading_Style_Sheets<br />
[5] Selektoren: http:// api. jquery. com/ category/ selectors/<br />
[6] Traversing: http:// api. jquery. com/ category/ traversing/<br />
[7] Event Object: http:// api. jquery. com/ category/ events/ event-object/<br />
[8] Firebug: https:// addons. mozilla. org/ de/ firefox/ addon/ firebug/<br />
[9] Power Constructor: http:// www. crockford. com/ javascript/ inheritance. html<br />
[10] Closure-basierte Vererbung: http:// www. ruzee. com/ blog/ 2008/ 12/ javascript-in<br />
heritance-via-prototypes-and-closures<br />
www.linux-user.de<br />
11 | 12 29