this

Baseline Widely available

This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.

Das this-Schlüsselwort bezieht sich auf den Kontext, in dem ein Code, wie der Körper einer Funktion, ausgeführt werden soll. Am häufigsten wird es in Objektmethoden verwendet, wobei this auf das Objekt verweist, an das die Methode gebunden ist, und es somit ermöglicht, dieselbe Methode auf verschiedenen Objekten wiederzuverwenden.

Der Wert von this in JavaScript hängt davon ab, wie eine Funktion aufgerufen wird (Laufzeit-Bindung), nicht davon, wie sie definiert ist. Wenn eine normale Funktion als Methode eines Objekts aufgerufen wird (obj.method()), verweist this auf dieses Objekt. Wenn sie als eigenständige Funktion aufgerufen wird (nicht an ein Objekt gebunden: func()), verweist this typischerweise auf das globale Objekt (im Nicht-Strict-Modus) oder ist undefined (im Strict-Modus). Die Methode Function.prototype.bind() kann eine Funktion erstellen, deren this-Bindung sich nicht ändert, und die Methoden Function.prototype.apply() und Function.prototype.call() können ebenfalls den this-Wert für einen bestimmten Aufruf setzen.

Arrow-Funktionen unterscheiden sich in der Behandlung von this: Sie erben this aus dem übergeordneten Gültigkeitsbereich zur Zeit ihrer Definition. Dieses Verhalten macht Arrow-Funktionen besonders nützlich für Rückrufe und zur Wahrung des Kontexts. Arrow-Funktionen haben jedoch keine eigene this-Bindung. Daher kann ihr this-Wert nicht durch die Methoden bind(), apply() oder call() gesetzt werden und verweist in Objektmethoden nicht auf das aktuelle Objekt.

Probieren Sie es aus

const test = {
  prop: 42,
  func() {
    return this.prop;
  },
};

console.log(test.func());
// Expected output: 42

Syntax

js
this

Wert

Im Nicht-Strict-Modus ist this immer eine Referenz auf ein Objekt. Im Strict-Modus kann es jeden Wert annehmen. Weitere Informationen zur Bestimmung des Wertes finden Sie in der Beschreibung unten.

Beschreibung

Der Wert von this hängt vom Kontext ab, in dem es erscheint: Funktion, Klasse oder globaler Kontext.

Funktionskontext

Innerhalb einer Funktion hängt der Wert von this davon ab, wie die Funktion aufgerufen wird. Betrachten Sie this als einen versteckten Parameter einer Funktion – ähnlich wie die in der Funktionsdefinition deklarierten Parameter ist this eine Bindung, die die Sprache für Sie erstellt, wenn der Funktionskörper ausgewertet wird.

Bei einer normalen Funktion (nicht einer Arrow-Funktion, gebundenen Funktion usw.) ist der Wert von this das Objekt, auf das die Funktion zugegriffen wird. Mit anderen Worten, wenn der Funktionsaufruf die Form obj.f() hat, verweist this auf obj. Zum Beispiel:

js
function getThis() {
  return this;
}

const obj1 = { name: "obj1" };
const obj2 = { name: "obj2" };

obj1.getThis = getThis;
obj2.getThis = getThis;

console.log(obj1.getThis()); // { name: 'obj1', getThis: [Function: getThis] }
console.log(obj2.getThis()); // { name: 'obj2', getThis: [Function: getThis] }

Beachten Sie, wie die Funktion dieselbe bleibt, aber je nachdem, wie sie aufgerufen wird, der Wert von this unterschiedlich ist. Dies ist analog dazu, wie Funktionsparameter funktionieren.

Der Wert von this ist nicht das Objekt, das die Funktion als eigene Eigenschaft hat, sondern das Objekt, das zum Aufrufen der Funktion verwendet wird. Dies können Sie beweisen, indem Sie eine Methode eines Objekts in der Prototypkette aufrufen.

js
const obj3 = {
  __proto__: obj1,
  name: "obj3",
};

console.log(obj3.getThis()); // { name: 'obj3' }

Der Wert von this ändert sich immer basierend darauf, wie eine Funktion aufgerufen wird, selbst wenn die Funktion bei der Erstellung einem Objekt zugewiesen wurde:

js
const obj4 = {
  name: "obj4",
  getThis() {
    return this;
  },
};

const obj5 = { name: "obj5" };

obj5.getThis = obj4.getThis;
console.log(obj5.getThis()); // { name: 'obj5', getThis: [Function: getThis] }

Wenn der Wert, auf den die Methode zugreift, ein primitiver Wert ist, wird this ebenfalls ein primitiver Wert sein – aber nur, wenn sich die Funktion im Strict-Modus befindet.

js
function getThisStrict() {
  "use strict"; // Enter strict mode
  return this;
}

// Only for demonstration — you should not mutate built-in prototypes
Number.prototype.getThisStrict = getThisStrict;
console.log(typeof (1).getThisStrict()); // "number"

Wenn die Funktion aufgerufen wird, ohne auf etwas zuzugreifen, wird this undefined sein – aber nur, wenn sich die Funktion im Strict-Modus befindet.

js
console.log(typeof getThisStrict()); // "undefined"

Im Nicht-Strict-Modus stellt ein spezieller Prozess namens this Substitution sicher, dass der Wert von this immer ein Objekt ist. Das bedeutet:

  • Wenn eine Funktion mit this auf undefined oder null aufgerufen wird, wird this durch globalThis ersetzt.
  • Wenn die Funktion mit this auf einen primitiven Wert aufgerufen wird, wird this durch das Wrapper-Objekt des primitiven Wertes ersetzt.
js
function getThis() {
  return this;
}

// Only for demonstration — you should not mutate built-in prototypes
Number.prototype.getThis = getThis;
console.log(typeof (1).getThis()); // "object"
console.log(getThis() === globalThis); // true

In typischen Funktionsaufrufen wird this implizit als Parameter durch das Präfix der Funktion (den Teil vor dem Punkt) übergeben. Sie können den Wert von this auch explizit mit den Methoden Function.prototype.call(), Function.prototype.apply() oder Reflect.apply() setzen. Mit Function.prototype.bind() können Sie eine neue Funktion mit einem bestimmten Wert von this erstellen, der unabhängig davon, wie die Funktion aufgerufen wird, unverändert bleibt. Bei der Verwendung dieser Methoden gelten die oben genannten this Substitutionsregeln noch immer, wenn die Funktion nicht im Strict-Modus ist.

Rückrufe

Wenn eine Funktion als Rückruf übergeben wird, hängt der Wert von this davon ab, wie der Rückruf aufgerufen wird, was vom Implementierer der API bestimmt wird. Rückrufe werden typischerweise mit einem this-Wert von undefined aufgerufen (direkter Aufruf, ohne an ein Objekt gebunden zu sein), was bedeutet, dass der Wert von this im Nicht-Strict-Modus das globale Objekt ist (globalThis). Dies ist der Fall für iterative Array-Methoden, den Promise()-Konstruktor usw.

js
function logThis() {
  "use strict";
  console.log(this);
}

[1, 2, 3].forEach(logThis); // undefined, undefined, undefined

Einige APIs erlauben es, einen this-Wert für Aufrufe des Rückrufs festzulegen. Zum Beispiel akzeptieren alle iterativen Array-Methoden und verwandte Methoden wie Set.prototype.forEach() einen optionalen thisArg-Parameter.

js
[1, 2, 3].forEach(logThis, { name: "obj" });
// { name: 'obj' }, { name: 'obj' }, { name: 'obj' }

Gelegentlich wird ein Rückruf mit einem this-Wert aufgerufen, der nicht undefined ist. Zum Beispiel werden der reviver-Parameter von JSON.parse() und der replacer-Parameter von JSON.stringify() beide mit this auf das Objekt gesetzt, zu dem die Eigenschaft gehört, die geparst/serialisiert wird.

Arrow-Funktionen

In Arrow-Funktionen behält this den Wert des umgebenden lexikalischen Kontexts. Mit anderen Worten, beim Auswerten des Körpers einer Arrow-Funktion wird keine neue this-Bindung erstellt.

Zum Beispiel ist in globalem Code this immer globalThis, unabhängig von der Striktmode, aufgrund der [globalen Kontex]bindung:

js
const globalObject = this;
const foo = () => this;
console.log(foo() === globalObject); // true

Arrow-Funktionen erstellen eine closure über den this-Wert ihres umgebenden Gültigkeitsbereichs, was bedeutet, dass Arrow-Funktionen sich verhalten, als wären sie "automatisch gebunden" — egal, wie sie aufgerufen werden, this wird auf den Wert gebunden, den es beim Erstellen der Funktion hatte (im obigen Beispiel das globale Objekt). Dasselbe gilt für Arrow-Funktionen, die innerhalb anderer Funktionen erstellt werden: Ihr this bleibt das des umgebenden lexikalischen Kontexts. Beispiel siehe unten.

Darüber hinaus wird bei der Verwendung von Arrow-Funktionen mit call(), bind() oder apply() der thisArg-Parameter ignoriert. Sie können jedoch weiterhin andere Argumente mit diesen Methoden übergeben.

js
const obj = { name: "obj" };

// Attempt to set this using call
console.log(foo.call(obj) === globalObject); // true

// Attempt to set this using bind
const boundFoo = foo.bind(obj);
console.log(boundFoo() === globalObject); // true

Konstruktoren

Wenn eine Funktion als Konstruktor verwendet wird (mit dem new-Schlüsselwort), wird ihr this an das neue Objekt gebunden, das gerade erstellt wird, unabhängig davon, auf welches Objekt die Konstruktorfunktion zugegriffen wird. Der Wert von this wird der Wert des new-Ausdrucks, es sei denn, der Konstruktor gibt einen anderen nicht-primitiven Wert zurück.

js
function C() {
  this.a = 37;
}

let o = new C();
console.log(o.a); // 37

function C2() {
  this.a = 37;
  return { a: 38 };
}

o = new C2();
console.log(o.a); // 38

Im zweiten Beispiel (C2), da ein Objekt während der Konstruktion zurückgegeben wurde, wird das neue Objekt, an das this gebunden war, verworfen. (Dies macht im Wesentlichen die Aussage this.a = 37; zu einem „toten Code“. Es ist nicht genau tot, da es ausgeführt wird, aber es kann ohne äußere Effekte eliminiert werden.)

super

Wenn eine Funktion in der super.method()-Form aufgerufen wird, ist das this innerhalb der method-Funktion derselbe Wert wie der this-Wert im Kontext des super.method()-Aufrufs und ist in der Regel nicht gleich dem Objekt, auf das super verweist. Dies liegt daran, dass super.method kein Objektmitglied-Zugriff wie die oben genannten ist – es handelt sich um eine spezielle Syntax mit unterschiedlichen Bindungsregeln. Beispiele finden Sie im super-Referenz.

Klassenkontext

Eine Klasse kann in zwei Kontexte unterteilt werden: statisch und Instanz. Konstruktoren, Methoden und Initialisierungen von Instanzfeldern (öffentlich oder privat) gehören zum Instanzkontext. Statische Methoden, Initialisierungen von statischen Feldern und statische Initialisierungsblöcke gehören zum statischen Kontext. Der this-Wert ist in jedem Kontext unterschiedlich.

Klassenkonstruktoren werden immer mit new aufgerufen, daher ist ihr Verhalten dasselbe wie bei Funktionskonstruktoren: Der this-Wert ist die neu erstellte Instanz. Klassenmethoden verhalten sich wie Methoden in Objektliteralen – der this-Wert ist das Objekt, auf das die Methode zugegriffen wird. Wenn die Methode nicht auf ein anderes Objekt übertragen wird, ist this im Allgemeinen eine Instanz der Klasse.

Statische Methoden sind keine Eigenschaften von this. Sie sind Eigenschaften der Klasse selbst. Daher wird in der Regel auf sie über die Klasse zugegriffen und this ist der Wert der Klasse (oder einer Unterklasse). Statische Initialisierungsblöcke werden ebenfalls mit this auf die aktuelle Klasse ausgewertet.

Feldinitialisierungen werden ebenfalls im Kontext der Klasse ausgewertet. Instanzfelder werden mit this auf die Instanz gesetzt, die gerade erstellt wird. Statische Felder werden mit this auf die aktuelle Klasse gesetzt. Aus diesem Grund sind Arrow-Funktionen in Feldinitialisierungen an die Instanz für Instanzfelder und an die Klasse für statische Felder gebunden.

js
class C {
  instanceField = this;
  static staticField = this;
}

const c = new C();
console.log(c.instanceField === c); // true
console.log(C.staticField === C); // true

Abgeleitete Klassenkonstruktoren

Im Gegensatz zu Basisklassenkonstruktoren haben abgeleitete Konstruktoren keine anfängliche this-Bindung. Das Aufrufen von super() erstellt eine this-Bindung im Konstruktor und hat im Wesentlichen die Wirkung, die folgende Codezeile auszuführen, wobei Base die Basisklasse ist:

js
this = new Base();

Warnung: Der Verweis auf this vor dem Aufruf von super() wird einen Fehler auslösen.

Abgeleitete Klassen dürfen nicht zurückkehren, bevor super() aufgerufen wird, es sei denn, der Konstruktor gibt ein Objekt zurück (sodass der this-Wert überschrieben wird) oder die Klasse hat überhaupt keinen Konstruktor.

js
class Base {}
class Good extends Base {}
class AlsoGood extends Base {
  constructor() {
    return { a: 5 };
  }
}
class Bad extends Base {
  constructor() {}
}

new Good();
new AlsoGood();
new Bad(); // ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor

Globaler Kontext

Im globalen Ausführungskontext (außerhalb von Funktionen oder Klassen; kann innerhalb von Blöcken oder Arrow-Funktionen definiert im globalen Umfang sein) hängt der this-Wert davon ab, in welchem Ausführungskontext das Skript läuft. Wie bei Rückrufen wird der this-Wert von der Laufzeitumgebung (dem Aufrufer) bestimmt.

Auf der obersten Ebene eines Skripts bezieht sich this auf globalThis, unabhängig davon, ob im Strict-Modus oder nicht. Dies ist im Allgemeinen dasselbe wie das globale Objekt — zum Beispiel, wenn die Quelle innerhalb eines HTML