Weiter führender Hinweis: Tennet Correspondence Principle (test of lambda abstraction)
Blocks (aber nicht für return, break, continue, this, arguments, var, function): {…} ≡ (function(){…})();
Expressions (aber nicht für this, arguments: (…) ≡ (function(){return …;})()
Eine innere Funktion, die in einer äußeren Funktion erzeugt wird, hat einen "unsichtbaren Zugriff" auf die inneren Variablen der äußeren Funktion. Die innere Funktionen kann die Variablen der äußeren Funktionen (ähnlich wie globale Variablen) nutzen. Dies wird als Closure bezeichnet und ist die Quelle einer enormen Ausdruckskraft.
Der funktion-interne Geltungsbereich von Variablen bewirkt,
daß innere Funktionen Zugriff auf die Werte von Variablen
in der umschließenden, äußere Funktion
(außer this
, arguments
) haben.
Eine Closure entspricht der Benutzung von (freie, pseudo globalen) Variablen in einer Funktion, die aus übergeordneten Gültigkeitsbereichen kommen und statisch bzw. lexikalisch in der zurück gegebenen Funktion gespeichert werden. Infolge der (mit-) gespeicherten Gültigkeitsbereiche kann die Funktion auf diese freie Variablen zugreifen.
Zur Einführung in Closure werden einfache Beispiele betrachtet.
Es gibt einen (festen) Array names
, der Namen enthält.
Der Zugriff kann mit Hilfe der Array-Indizierung erfolgen.
Z.B. zeigt alert(names[2])
den Namen 'Christian' an.
Die folgende Funktion get_name(n)
gibt den n-ten Namen zurück.
Die Funktion kann den Array-Zugriff kontrollieren.
Nachteilig ist, daß der names
-Array global ist.
Die folgende Funktion get_name(n)
verwendet
einen inneren Array names
.
Nachteilig ist, daß die Ausführung des Zugriffes recht langsam ist,
weil bei jedem Funktionsaufruf der Array neu angelegt wird.
Die nachfolgende Methode verwendet Closure.
Beim ersten Aufruf der "Wrapper-Funktion" wird der innere Array names
angelegt
und der Rückgabewert der namenlosen inneren Funktion wird zu get_name(n)
.
Der Array names
existiert dann privat.
obj gibt wegen function(){... return {...};}(); ein Objekt {...} zurück, das 2 Methoden enthält, die das Recht haben, auf die private Variable val zuzugreifen. obj kann etwa verwendet werden wie obj.erhoehe(1.23) und obj.get_val()
Teste href="javascript:alert(obj.get_val())" und auch onclick="alert(obj.get_val());return false;"
Die folgende Funktion soll ohne new-Präfix verwendet werden. Ein Aufruf von quo liefert ein Objekt zurück, das eine Funktion .get_status() enthält.
In var myQuo = quo('Hallo Welt'); entsprich myQuo der Referenz auf das zurückgegeben Objekt. Die .get_status()-Methode darf auf den privaten Bereich (hier der Parameter) von quo zugreifen, obwohl quo bereits zurückgekehrt ist. Die .get_status()-Methode besitztkeinen Zugriff auf eine Kopie des Parameters, sondern auf den Parameter selbst. Dies wird als Closure bezeichnet.
Teste myQuo.get_status()
Alle a-Tags mit titel-Attribut sollen den title-Text in einer confirm-Box ausgeben. "confirm" meint bestätigen. Eine confirm-Box hat einen Anzeigetext und zwei Bottons (OK und Cancel).
a-Tags erhalten im titel-Attribut oft Erklärungen und zusätzliche Hinweise. blinde Menschen, die einen Screen-Reader verwenden, können das eingeblendete title-Tooltip (hover, mouse-over) nicht erkennen. Um den title-Hinweis lesen zu können, muß der Screenreader umgeschalten werden.
Die zu entwickelnde Funktion title2confirm() soll alle Elementen a[i] vom Array var a = document.getElementsByTagName('a') der HTML-Seite durchlaufen und den title-text a[i].title jedes a[i]-Elementes als confirm-text in einen onclick-Handler einfügen.
Ein onclick-Ereignis wird vor der href-Ausführung ausgeführt. Nach dem onclick-Ereignis wird href nur dann ausgeführt, wenn der onclick-Handler true zurück gibt.
<a href="javascript:title2confirm('on')" > [+] confirm on </a> bzw. mit <a href="javascript:title2confirm('off')"> [-] confirm off </a>
window.onload = function() { title2confirm('on'); };eingeschalten werden können.
Eine weitere Funktion toggle_confirm(that) soll es ermöglichen, per a-Tag
<a href="javascript:void(0)" onclick="visu.toggle_confirm(this);">[+] confirm</a>
die "title-in-confirm-kopierung" an und aus zu schalten ([+] bzw. [-]).
Zum Umschalten von confirm 'on' auf confirm 'off' und umgekehrt, können zwei a-Tags, eines mit title2confirm('on') und das andere mit title2confirm('off') verwendet werden, etwa
<a href="javascript:void(0)" onclick="title2confirm('on')" > Schalte auf on </a>, <a href="javascript:void(0)" onclick="title2confirm('off')"> Schalte auf off </a>
Bildschirm-Platz-sparender ist die Umschaltung mit lediglich einem a-Tag. Hierzu kann title2confirm(arg) verwendet werden, indem anstelle eines Strings 'on' oder 'off' das this des aufrufenden a-Tags verwendet wird. Achtung! href liefert nicht das this vom a-Tag. Deshalb wird onclick verwendet.
<a href="javascript:void(0)" onclick="title2confirm(this);">[+] confirm</a>
"[+] confirm" schaltet auf "[-] confirm" und umgekehrt. "[+] confirm" schaltet die confirm-Anzeige-Aktionen ein. Alle a-Tags mit confirm haben dann ein pre-Zeichen "(c) ..." und zeigen damit an, daß erst eine confirm-Abfrage bestätigt werden muß. "[-] confirm" schaltet die confirm-Aktionen ab. Alle pre-Zeichen "(c) ..." werden gelöscht.
teste: Schaltet confirm ein bzw. aus mit
[+] toggle_confirm(this)
teste: Wirkungen von 'on' bzw. 'off':
teste
a-Tag mit href alert('href0') und title="title0"
teste
a-Tag mit href alert(this === window) und title-text
teste: Nicht-Auswirkungen auf fehlendes title- und vorhandenes onclick-Attribut bei 'on' bzw. 'off':
teste
a-Tag mit href alert('href1') und ohne title-Attribut
teste
a-Tag mit href alert('href2') und
title="title bleibt" und
onclick="alert('Was liefert this === window bei onclick? ..."
Die eingebaute .prototype-Methode ist umständlich zu schreiben und nicht intuitiv verständlich. Deshalb kann durchgängig die (nachfolgend angegebene) .method-Methode von Crockford verwendet werden.
Nachfolgend werden mit der .method-Methode die Funktionen deentityify und entityify definiert, die dann wie eingebaute ECMAScript-String-Methoden verwendet werden, wie z.B. var ss = "<&'>".entityify();
Anzeige:
Die Funktion fade_simple = function(node, ms) soll den Grünanteil 'gg'der Hintergrundfarbe zeitgesteuert (Closure) setzen: gg = '00', '11', '22', '33', '44', '55', '66', '77', '88', '99', 'aa', 'bb', 'cc', 'dd', 'ee', 'ff'.
Hier ist die Ausführung der Funktion fade_simple(document.getElementById('FADE_SIMPLE')): Test
Dies ist eine Erweiterung des vorherigen Beispieles, wobei die inneren Hilfsfunktionen r_g_b_from(col) und function hex_from(dez) verwendet werden.
Hier ist die Ausführung der Funktion fade(document.body): Test
Mit der folgenden Funktion add_handlers_to sollen DOM-Elementen eines Array's jeweils einige CSS-Attribute und ein onclick-Ereignis hinzu gefügt werden.
Wichtig ist, dass die Handlerfunktion nicht an die Variable i, sondern an den Wert von i beim Click-Ereignis gebunden wird.
Lösung: Es wird eine Funktion = function (i) {...}(i) definiert, die sofort mit i aufgerufen wird. Dadurch wird eine Eventhandler-Funktion zurück gegeben, die an den übergebenen Wert von i gebunden ist (und nicht an add_handlers_to). Diese zurück gegebene Funktion wird dann onclick zugewiesen.
Zum Testen bitte auf die id's klicken. id0 id1 id2