Was Sie wissen sollten this
this
(auch bekannt als "der Kontext") ist ein spezielles Schlüsselwort in jeder Funktion und sein Wert hängt nur davon ab, wie die Funktion aufgerufen wurde, nicht davon, wie / wann / wo sie definiert wurde. Es wird nicht wie andere Variablen von lexikalischen Bereichen beeinflusst (mit Ausnahme der Pfeilfunktionen, siehe unten). Hier sind einige Beispiele:
function foo() {
console.log(this);
}
// normal function call
foo(); // `this` will refer to `window`
// as object method
var obj = {bar: foo};
obj.bar(); // `this` will refer to `obj`
// as constructor function
new foo(); // `this` will refer to an object that inherits from `foo.prototype`
Weitere this
Informationen finden Sie in der MDN-Dokumentation .
Wie man sich auf das Richtige bezieht this
Nicht benutzen this
Sie möchten eigentlich nicht this
speziell auf das Objekt zugreifen , auf das es sich bezieht . Aus diesem Grund besteht eine einfache Lösung darin, einfach eine neue Variable zu erstellen, die sich auch auf dieses Objekt bezieht. Die Variable kann einen beliebigen Namen haben, aber gebräuchliche sind self
und that
.
function MyConstructor(data, transport) {
this.data = data;
var self = this;
transport.on('data', function() {
alert(self.data);
});
}
Da self
es sich um eine normale Variable handelt, befolgt sie die Regeln des lexikalischen Bereichs und ist innerhalb des Rückrufs zugänglich. Dies hat auch den Vorteil, dass Sie auf den this
Wert des Rückrufs selbst zugreifen können .
Expliziter Satz this
des Rückrufs - Teil 1
Es könnte so aussehen, als hätten Sie keine Kontrolle über den Wert von, this
da sein Wert automatisch festgelegt wird, aber das ist tatsächlich nicht der Fall.
Jede Funktion hat die Methode .bind
[docs] , die eine neue Funktion mit this
an einen Wert gebundenem Wert zurückgibt . Die Funktion hat genau das gleiche Verhalten wie die von Ihnen aufgerufene .bind
, nur dass diese this
von Ihnen festgelegt wurde. Unabhängig davon, wie oder wann diese Funktion aufgerufen wird, this
wird immer auf den übergebenen Wert verwiesen.
function MyConstructor(data, transport) {
this.data = data;
var boundFunction = (function() { // parenthesis are not necessary
alert(this.data); // but might improve readability
}).bind(this); // <- here we are calling `.bind()`
transport.on('data', boundFunction);
}
In diesem Fall binden wir die Rückrufe this
an den Wert von MyConstructor
's this
.
Hinweis: Verwenden Sie beim Binden des Kontexts für jQuery stattdessen jQuery.proxy
[docs] . Der Grund dafür ist, dass Sie den Verweis auf die Funktion nicht speichern müssen, wenn Sie einen Ereignisrückruf aufheben. jQuery erledigt das intern.
ECMAScript 6 führt Pfeilfunktionen ein , die als Lambda-Funktionen betrachtet werden können. Sie haben keine eigene this
Bindung. Stattdessen this
wird im Gültigkeitsbereich genau wie bei einer normalen Variablen nachgeschlagen. Das heißt, Sie müssen nicht anrufen .bind
. Dies ist nicht das einzige spezielle Verhalten, das sie haben. Weitere Informationen finden Sie in der MDN-Dokumentation.
function MyConstructor(data, transport) {
this.data = data;
transport.on('data', () => alert(this.data));
}
Set this
des Rückrufs - Teil 2
Einige Funktionen / Methoden, die Rückrufe akzeptieren, akzeptieren auch einen Wert, auf den sich die Rückrufe this
beziehen sollten. Dies ist im Grunde dasselbe wie das Binden selbst, aber die Funktion / Methode erledigt es für Sie. Array#map
[docs] ist eine solche Methode. Seine Unterschrift lautet:
array.map(callback[, thisArg])
Das erste Argument ist der Rückruf und das zweite Argument ist der Wert, this
auf den Bezug genommen werden soll. Hier ist ein erfundenes Beispiel:
var arr = [1, 2, 3];
var obj = {multiplier: 42};
var new_arr = arr.map(function(v) {
return v * this.multiplier;
}, obj); // <- here we are passing `obj` as second argument
Hinweis: Ob Sie einen Wert für übergeben können oder nicht, this
wird normalerweise in der Dokumentation dieser Funktion / Methode angegeben. Zum Beispiel beschreibt die $.ajax
Methode [docs] von jQuery eine Option namens context
:
Dieses Objekt wird zum Kontext aller Ajax-bezogenen Rückrufe.
Häufiges Problem: Verwenden von Objektmethoden als Rückruf- / Ereignishandler
Eine weitere häufige Manifestation dieses Problems ist die Verwendung einer Objektmethode als Rückruf- / Ereignishandler. Funktionen sind in JavaScript erstklassige Bürger, und der Begriff "Methode" ist nur ein umgangssprachlicher Begriff für eine Funktion, die ein Wert einer Objekteigenschaft ist. Diese Funktion hat jedoch keinen spezifischen Link zu ihrem "enthaltenden" Objekt.
Betrachten Sie das folgende Beispiel:
function Foo() {
this.data = 42,
document.body.onclick = this.method;
}
Foo.prototype.method = function() {
console.log(this.data);
};
Die Funktion this.method
wird als Klickereignishandler zugewiesen. Wenn Sie jedoch auf klicken document.body
, wird der Wert protokolliert undefined
, da sich der Wert im Ereignishandler this
auf document.body
die Instanz von und nicht auf die Instanz von bezieht Foo
.
Wie bereits eingangs erwähnt this
, hängt es davon ab, wie die Funktion aufgerufen wird und nicht davon, wie sie definiert ist .
Wenn der Code wie folgt lautet, ist es möglicherweise offensichtlicher, dass die Funktion keinen impliziten Verweis auf das Objekt hat:
function method() {
console.log(this.data);
}
function Foo() {
this.data = 42,
document.body.onclick = this.method;
}
Foo.prototype.method = method;
Die Lösung ist dieselbe wie oben erwähnt: Wenn verfügbar, verwenden Sie .bind
diese Option, um explizit this
an einen bestimmten Wert zu binden
document.body.onclick = this.method.bind(this);
oder rufen Sie die Funktion explizit als "Methode" des Objekts auf, indem Sie eine anonyme Funktion als Rückruf- / Ereignishandler verwenden und das Objekt ( this
) einer anderen Variablen zuweisen :
var self = this;
document.body.onclick = function() {
self.method();
};
oder verwenden Sie eine Pfeilfunktion:
document.body.onclick = () => this.method();