V. 8.7 (27.03.2012)

Infos

Download

Theorie OOP mit JavaScript

Schnellsuche

OOP mit JavaScript - Closures - Feinheiten

1. Vorwort

Ein Hinweis

Früher habe ich mich an dieser Stelle ordentlich ausgekotzt und mich über Closures ziemlich abfällig geäußert. Mann, war das blauäugig. Mittlerweile weiß ich aber, dass ich da einen ziemlichen Müll von mir gegeben habe. Darum sage ich mea culpa und versuche nun, meinen vorherigen Bockmist zu korrigieren.

Da ich selber immer noch nicht der absolute Ober-JavaScript-Experte bin, seid ein wenig skeptisch beim dem, was ich euch nun erzähle. Wenn jemand von euch meint, dass ich falsch liege, so möge mir die Person doch bitte eine Mail schicken. Eine gute Seite zu dem Thema ist die von Arno, der mir mehrmals schon geholfen hat. An dieser Stelle noch mal Danke dafür.

2. Ein Beispiel

..., das übrigens von besagtem Arno ist. Ich schmücke mich nicht gerne mit fremden Federn. Kommen wir mal zu der hier schon mehrfach erwähnten Problematik (siehe Tutorials), wo man in einer Schleife einen Event-Handler auf einen Link legt. Der Standardcode sieht dann vom Prinzip her meistens so aus.


var links document.getElementsByTagName('a');
for (var 
0links.lengthi++) {
  
links[i].onclick = function (e) {
    
e.preventDefault();
    
alert('Link Nr.: ' + (1));
  }
}

Das kann natürlich nicht funktionieren, da vor einem Klick die Schleife bereits durchlaufen wurde und man immer den letzten Wert bekommt. Ach ja, das preventDefault verhindert, dass man zu dem angeklickten Link kommt. Nur nicht im IE, da benötigt man wieder eine Extrawurst.

3. Ein Closure


var links document.getElementsByTagName('a');
for (var 
0links.lengthi++) {
  
links[i].onclick 
  (
    function () {
      var 
link i;
      return function (
e) {
        
e.preventDefault();
        
alert('Link Nr.: ' + (link 1));
      }
    }
  )();
}

Erläuterung

Ehrlich gesagt habe ich mit so einer Vorgehensweise noch nie gearbeitet. Darum hoffe ich mal, dass meine Erläuterungen hierzu korrekt sind. Zunächst mal bauen wir uns mit links[i].onclick = (...)() einen Selbstzünder, der sofort ausgeführt wird. Innerhalb dieses Selbstzünders erzeugen wir nun ein Closure, indem wir den Wert von i in der Variable link abspeichern (var link = i;). Somit steht also immer der richtige Wert zur Verfügung.

Den Rest benötigen wir nur, um zu verhindern, dass man dann zum eigentlichen Link kommt. Die anonyme Funktion function (e) verhindert, dass unser Selbstzünder direkt nach dem Laden der Seite ausgelöst wird, sondern nur bei einem Klick auf einen Link läuft. Das return ist dabei der Rückgabewert, der benötigt wird um preventDefault auszulösen. Das Prinzip ist dasselbe wie bei einem Formular abschicken. Also die Sache mit dem <form ... onsubmit="return checkForm();">.

4. Die Sache mit dem this

Das Problem habe ich euch ja schon an dieser Stelle gezeigt. Auch wenn ich mich hier nicht um die Details kümmere (interessiert eh keine Sau), so soll es sich hier ebenfalls um ein Closure handeln. Wenn es auch etwas Seltsames.


function Konstruktor() {
  var 
that this;
  ...
}

weiter zum nächsten Abschnitt