Objekte, die sich selber untersuchen
Bei jedem Aufruf der Funktion wird dieses Argument - sozusagen hinter den Kulissen - zusammen mit einem Zeiger auf das Objekt, das die Funktion aufrief, übergeben. this hat eine ähnliche Funktion wie das »sie« in diesem Satz: »Martina stand früh auf, denn sie wollte Kurts Ankunft nicht verpassen«. Durch »sie« ist klar, dass die zuerst erwähnte Martina gemeint ist.
In objektorientierten Sprachen brauchen wir etwas, um auf das aktuelle Objekt zuzugreifen, das gerade vom Script behandelt wird. Dank Javascript this können sich Objekte selbst untersuchen und Auskunft über ihre Eigenschaften geben.
Jede Funktion hat ihren eigenen Speicherplatz, in dem ihre Variablen und Eigenschaften liegen. Der Zugriff auf eine bestimmte Variable passiert durch den Raum oder Scope – die Funktion, das Objekt –, in dem sie definiert ist. Wenn im Script keine Funktion definiert wurde, passiert alles im globalen Umfeld.
Aber selbst dann gibt es ein »this« – das globale Umfeld ist das window-Objekt.
this is a moving target
this hat keinen Wert, bis ein Objekt die Funktion aufruft, in der this definiert ist.
Javascript this gibt es in jedem Funktions- oder globalen Umfeld. Aber in jedem Umfeld hat this eine andere Zuordnung – ist an ein anderes Element gebunden.
Der Wert von this innerhalb einer Funktion hängt von dem Objekt ab, das die Funktion aufgerufen hat. Im Bild oben ist this in function b einmal das div-Element, auf dem die Funktion aufgerufen wurde, und ein anderes this, wenn die Funktion b auf dem form-Element aufgerufen wurde. Für Einsteiger immer wieder ein Mysterium …
Javascript ist eine spätbindende (late binding) Programmiersprache. Verglichen mit anderen Programmiersprache bindet Javascript sein this sogar außerordentlich spät. this wird nicht während der Compilierung gebunden, auch nicht zur Laufzeit wie in anderen Programmiersprachen, sondern zum Zeitpunkt des Aufrufs. Das verstört selbst erfahrene Programmierer, die von objektorientierten Programmiersprachen kommen.
this bei events auf HTML-Elementen
Das mag kein Beispiel für gutes Javascript sein, denn das ist altmodisches inline-Javascript. Aber nichts könnte Javascript this besser in Szene setzen:
<div onmouseover="this.innerHTML='Ich bin jetzt this!'"></div>
Wenn die Maus über das HTML div hovert, soll dieses div den Text Ich bin jetzt this zeigen.
Javascript this bei Funktionen
Und einen Schritt weiter: das Javascript this in einer Funktion
<div> <button id="but">Klick!</button> </div> … <script type="text/javascript"> if (document.getElementById('but')) { const button = document.getElementById('but'); button.onclick = function() { this.innerHTML = "ICH BIN THIS!"; } } </script>
In diesem Fall ist der Eigentümer oder Aufrufer der Funktion this.
Was ist dieses this?
this ist ein bewegliches Ziel. Ein paar handfeste Regeln:
-
Außerhalb von allen Funktionen verweist this auf das globale Objekt. In einem Browser ist das traditionell das Window-Objekt.
console.log ("this.location " + this.location);
gibt die URL der aktuelle Seite aus – ein Element des Window-Objekts.
-
In einem Event Handler (z.B. einem onclick) verweist this auf das DOM-Element, auf dem das Ereignis ausgelöst wurde.
document.getElementById ('foo').onclick = function () { alert (this.nodeName); }
-
Wenn eine Funktion als Constructor aufgerufen wird, wird ein neues Objekt erzeugt und this an das Objekt gebunden.
function Foo () { this.bar = 1; } new Foo().bar;
-
Wenn Javascript im Strict-Mode läuft, darf this nicht auf das globale Object (also Window in Browsern) verweisen. Wenn also eine Funktion nicht als Methode eines Objekts aufgerufen wird oder this nicht manuell durch call oder apply an ein Element gebunden wurde, liefert this undefined.
function loo () { return this; } console.log (loo()); // gibt aus: loo *** undefined
this im strict mode
In globalen Funktionen ist this im strict mode also undefined, nicht aber in Constructor-Funktionen.
let person = { vorname: "Penelope", nachname: "Barrymore", vollname: function () { console.log(this.vorname + " " + this.nachname); // Hätte auch so geschrieben werden können: console.log(person.vorname + " " + person.nachname); } }
Würden person.vornamen und person.nachname in der Constructor-Funktion anstelle von this.vorname und this.nachname benutzt, wären die Anweisungen u.U. nicht mehr eindeutig – z.B. wenn eine weitere globale Variable person (von der wir vielleicht nichts wissen) existiert. Derartige Fehler sind nicht einfach aufzufinden, darum wird hier this bevorzugt.
this mit bind neu definieren
Mit der bind-Methode kann this neu zugewiesen werden.
const myFlowers = { name : "Hortensie", getName : function () { return console.log (this.name); } }; myFlowers.getName();
const myFlowers = { name : "Hortensie", getName : function () { return console.log (this.name); } }; const moreFlowers = myFlowers.getName.bind ({"Nelke"}); moreFlowers ();
this in Arrow Functions
ES6 (ECMAScript) hat eine weitere Schreibweise mit neuen Verhalten mitgebracht: die Arrow Function. In einer Arrow Function bezieht sich this nicht auf das Objekt selbst, sondern auf das umfassende Objekt. Das reduziert die Verwirrung in inneren Funktionen in Javascript-Objekten.