1. April 2014 | 1 Comment Letzte Woche habe ich einiges zum Thema „Javascript und this“ geschrieben, unter anderem was sich in verschiedenen Kontexten innerhalb von this verbirgt. Heute geht es mit ein paar zusätzlichen Informationen weiter! Zunächst zeige ich euch, wie eine „ganz normale“ Funktion den Kontext und seine Parameter verarbeitet. // Very basic example var x = function (a, b) { console.log(this); console.log(a); console.log(b); }; x('a', 'b'); In der Javascript Konsole würde folgendes stehen: Window {...} "a" "b" this in Sub-Funktionen Wie vorletzte Woche kurz angerissen können verschachtelte Funktionen auf die Variablen der äußeren Funktionen zugreifen. Mit Ausnahme von this und arguments – ihr erinnert euch? Aufgrund dieser Tatsache sieht man relativ häufig folgenden kleinen workaround: // This and that. var obj = { method:function () { var that = this, x = function () { console.log(this); console.log(that); }; console.log(this); x(); } }; obj.method(); Dieses kleine Beispiel gibt uns folgendes aus: Object {method: function} // The outer "this" Window {...} // The inner "this" Object {method: function} // The inner "that" Clever oder? Aber es geht noch um einiges besser! Dazu müssen wir nur… Den Kontext selbst bestimmten Richtig gelesen: wir können in Javascript den this Kontext selbst bestimmen. Das ganze geht sogar ganz einfach sieht allerdings etwas komisch aus, weil wir direkt an den Funktionskörper eine Methode hängen… Aber das ist richtig so, in Javascript sind nämlich auch Funktionen Objektinstanzen! Wir haben drei Methoden zu auwahl: bind(), call() und apply(). bind() Zuerst bringen wir bind() ins Spiel… // A bit more dynamic var x = function (a, b) { console.log(this); console.log(a); console.log(b); }.bind('my context', 'param1', 'param2'); x('a', 'b'); Dieses Beispiel liefert uns nun die folgende Ausgabe in der Konsole: String {0: "m", 1: "y", 2: " ", 3: "c", 4: "o", 5: "n", 6: "t", 7: "e", 8: "x", 9: "t", length: 10} param1 param2 Sobald man bind() mit mehr als einem Parameter verwendet, werden die Funktionsparameter dauerhaft überschrieben… Das kann nicht rückgängig gemacht haben – selbst wenn wir nochmal bind() aufrufen, also Achtung! Verwendet stattdessen lieber folgende Schreibweise: // The better alternative! var x = function (a, b) { console.log(this); console.log(a); console.log(b); }; x.bind('my context', 'param1', 'param2')('a', 'b'); Hier werden die Parameter der Funktion x nicht überschrieben, weil wir bind() zur Laufzeit verwenden anstatt beim deklarieren der Funktion. Und ja, in echtem Code wäre es totaler Unsinn die Parameter per bind() zu setzen und anschließend zu versuchen etwas anderes zu übergeben… 😉 call() Als zweite Methode stelle ich euch call() vor. Im Gegensatz zu bind() wird hier die Funktion oder die Methode nicht zurückgeliefert sondern direkt ausgeführt: // A bit more dynamic var x = function (a, b) { console.log(this); console.log(a); console.log(b); }; x.call('my context', 'param1', 'param2'); // Theoretically the same as: //x.bind('my context', 'param1', 'param2')(); // Or... //x.bind('my context')('param1', 'param2'); apply() Zuletzt bleibt nur noch apply() übrig. Diese Methode funktioniert ähnlich wie call(), nimmt aber nur zwei Parameter entgegen: // A bit more dynamic var x = function (a, b) { console.log(this); console.log(a); console.log(b); }; x.apply('my context', ['param1', 'param2']); Wie wir sehen übergeben wir ein Array mit Werten anstatt jeden Wert einzeln zu übergeben – das kann uns in Situationen helfen in denen wir mit dynamischen Arrays arbeiten (bzw. Arrays deren Größe wir nicht kennen). Und mit diesen Worten möchte ich mich auch schon für Heute von euch verabschieden! Vielleicht habt ihr noch ein paar Tipps zum Umgang mit this in Javascript? Lasst es mich in den Kommentaren wissen! Bis nächste Woche wünsche ich euch tollstes Frühlingswetter und natürlich Happy Coding!