OOP mit JavaScript - Konstruktorfunktionen - Besonderheiten
1. Die Sache mit dem this
Normalerweise handelt es sich dabei ja um einen Verweis auf das eigene Objekt. Und bei öffentlichen Methoden oder Eigenschaften trifft das sogar zu. Aber irgendein Vollhonk kam wohl im Vollrausch auf die Idee, bei JavaScript (respektive ECMA-Script) eine Ausnahme einzubauen. Der muss wohl genauso zugedröhnt gewesen sein wie der Typ, der das Boxmodell entworfen hat, oder die zweifelhafte Person, die für die Collapsing margins verantwortlich ist.
2. Der Zusammenhang
Wenn man innerhalb einer "privaten"/"globalen"/anonymen Methode/Funktion der entsprechenden Konstruktorfunktion mit this
arbeitet,
so verweist das nicht auf das eigene sondern auf das window
-Objekt! Wenn ich das genauer ausbaldowert habe, so werde ich natürlich
darüber etwas schreiben. Es hat auf jeden Fall damit zu tun, wem die Funktion/Methode gehört.
3. Der Zugriff
Will denn nun eine der oben aufgeführten Methoden auf eine öffentliche Eigenschaft oder Methode zugreifen, so funktioniert das natürlich
nicht über this
. Stattdessen speichert man vorher eine Referenz auf das eigene Objekt in einer Variablen ab. Über die
klappt dann auch der Zugriff.
function Konstruktor()
{
var that = this;
this.eigenschaft = 'blubber';
this.methode = function()
{
privateMethode();
}
function privateMethode()
{
alert (that.eigenschaft);
}
}
var obj = new Konstruktor;
obj.methode();
Erläuterung
Mit var that
wird gleich zu Beginn eine Referenz auf das eigene Objekt erzeugt. Die Details dazu kommen später. Viele Leute nehmen
anstelle des that
auch gerne das self
. Das verweist zwar ebenfalls auf das window
-Objekt, aber da man
das außer bei Frames eh nie braucht, kann man es auch getrost überschreiben. Obercoole "Brothaz from da Hood" nehmen auch gerne ein
thiz
dafür.
Eine Alternative
function Konstruktor()
{
this.eigenschaft = 'blubber';
this.methode = function()
{
privateMethode.call(this);
}
function privateMethode()
{
alert (this.eigenschaft);
}
}
var obj = new Konstruktor;
obj.methode();
Erläuterung
Da ich selber damit noch nicht gearbeitet habe, halte ich mich mit meinen Aussagen ein wenig zurück. Mit call
ruft man eine Funktion/Methode
auf. Dabei muss der erste Parameter ein Verweis auf das eigene Objekt sein. Gibt es weitere, so werden die einfach angehängt. In den Parametern der Funktion
selber wird er nicht aufgelistet. Die Details dazu liefer ich irgendwann nach.
4. "Globale" Methoden
Jetzt zeige ich euch mal, warum einige die so nennen. Gut andere sagen, dass es so was nicht gibt, aber mir gefällt die Bezeichnung, da sie meiner
Meinung nach recht einleuchtend ist. Also, wenn man in einer Konstruktorfunktion eine "globale" Methode erzeugt, so hängt
die automatisch im window
-Objekt drin, sobald eine Referenz/Instanz von der Konstruktorfunktion erzeugt worden ist. Ob so eine Vorgehensweise
nun besonders sinnvoll ist, sei mal dahingestellt.
function Konstruktor()
{
var that = this;
this.eigenschaft = 'blubb';
globaleMethode = function()
{
alert (that.eigenschaft);
}
}
var obj = new Konstruktor;
window.globaleMethode();
Erläuterung
Ich hoffe, ich rede jetzt keinen Blödsinn. Aber ich denke, dass es in etwa so abläuft. Zuerst erzeugen wir eine Konstruktorfunktion.
Dann wird per var obj = new Konstruktor;
ein Objekt erzeugt. Und dann hängt wegen des schon erwähnten Vollhonks die
Funktion globaleMethode
im window
-Objekt.
Trotzdem kann sie über die Referenzvariable that
noch auf die öffentliche Eigenschaft eigenschaft
zugreifen.
Ach ja, das window
beim Aufruf kann man sich getrost sparen, es reicht auch ein
var obj = new Konstruktor;
globaleMethode();
völlig aus. Wichtig ist nur, dass zuerst ein Objekt aus der Konstruktorfunktion erzeugt worden ist. Denn ohne das
var obj = new Konstruktor;
haut es euch eine Fehlermeldung um die Ohren.
5. Ein Tipp
Wer von euch das mit dem this
nicht glaubt, der kann das ganz einfach mit Firefox oder anderen zumindest halbwegs modernen Browsern mittels
einem alert(this)
testen. Denn kann bekommt ihr eine Meldung à la object Window
ausgegeben.
zurück zum vorherigen Abschnitt weiter zum nächsten Abschnitt