Skip to content

this in JavaScript und jQuery

Posted on:

Note: This post is from my old blog and thus written in German and potentially obsolete.

Wenn man in JavaScript mit Objekten und Konstruktoren arbeitet, oder häufig jQuery verwendet, kann es immer wieder vorkommen, dass man sich die Frage stellt: What is this?

this in JavaScript

this ist eines der Schlüsselwörter in JavaScript. Es bezieht sich auf einen bestimmten Wert, in der Regel ein Objekt. Definiert man z.B. eine Funktion einfach im globalen Namensraum, dann zeigt this auf das globale Objekt, im Browser also window:

function globaleFunktion() {
  console.log(this);
}

globaleFunktion(); // window

In diesem Fall macht die Verwendung allerdings wenig Sinn. Interessanter wird es wenn man mit Objekten arbeitet, z.B. um den eigenen Code zu strukturieren. Weist man einem Objekt dabei eine Methode zu, zeigt this innerhalb dieser auf das entsprechende Objekt:

var meinCode = {
  name: "Douglas",
  zeigeName: function () {
    console.log(this.name);
  },
};

meinCode.zeigeName(); // "Douglas"

Man könnte innerhalb von console.log auch meinCode.name schreiben, aber zum einen ist this kürzer, zum anderen würde es auch nach Änderung des Namens von meinCode immer noch auf das korrekte Objekt zeigen.

In meinem letzten Post zum Thema pseudoklassische Vererbung in JavaScript bin ich bereits auf this im Rahmen der Verwendung von Konstruktor-Funktionen eingegangen. Hier verweist es auf die aktuelle Instanz. Allerdings nur wenn diese mit Hilfe des new-Operators erzeugt wurde. Ansonsten verhält es sich wie im Fall der globalen Funktion, verweist also auf window.

var Person = function (name) {
  this.name = name;
  this.say = function () {
    return "Ich bin " + this.name;
  };
};

var Douglas = new Person("Douglas");
var John = new Person("John");

Douglas.say(); // "Douglas"
John.say(); // "John"

Auch beim Event-Handling kommt this zum Einsatz. Ausgehend vom DOM Level 0 Standard könnte das beim Abschicken eines Formulars folgendermaßen aussehen:

function formularSubmit() {
  console.log("Das Formular hat " + this.attributes.length + " Attribute.");
}

document.getElementById("meinFormular").onSubmit = formularSubmit;

this bezieht sich hier auf das DOM-Element welches den submit-Event auslöst. In diesem Fall also das Formular mit der Id meinFormular.

Beim fortgeschrittenen Event-Handling wird die Sache etwas komplizierter. Abgesehen davon, dass die von Microsoft als Weiterentwicklung des eben vorgestellten, traditionellen Event-Handling eingeführte Methode attachEvent von der des DOM Level 2 abweicht, diese lautet addEventListener, verweist this innerhalb der Methode nicht auf das aktuelle DOM-Element, sondern auf window.

Die Unterschiede der Browser beim Event-Handling waren mit ein Grund für die zunehmende Popularität von JavaScript-Bibliotheken wie Prototype, MooTools, YUI und jQuery.

this in jQuery

jQuery arbeitet viel mit anonymen Callback-Funktionen, u.a. beim Event-Handling. Innerhalb dieser Funktionen verweist this auf das aktuelle DOM-Element:

$("#meinFormular").submit(function () {
  console.log(this.id); // "meinFormular"
});

Um die von jQuery bereitgestellten Methoden auf das aktuelle DOM-Element anzuwenden, kann man dieses einfach in ein jQuery-Objekt umwanden, indem man this der bekannten $-Funktion übergibt:

$("#meinFormular").submit(function () {
  $(this).remove(); // entfernt das Element aus dem DOM
});

Wenn man jQuery um eigene Funktionalitäten erweitern möchte, kann man einfach ein Plugin schreiben. Innerhalb diesem verweist this prinzipiell auf das jQuery-Objekt, wobei sich der Kontext schnell ändern kann. Hierzu ein anschauliches Beispiel von Remy Sharpe:

jQuery.fn.newTarget = function () {
  // hier ist 'this' ein jQuery-Objekt, weshalb wir die each-Methode anwenden können
  return this.each(function () {
    // innerhalb dieser Callback-Funktion ist 'this' wieder das aktuelle DOM-Element
    if (this.host != window.location.host) {
      // das DOM-Element wird in ein jQuery-Objekt umgewandelt
      $(this).attr("target", "_new");
    }
  });
};