Warum funktioniert die Übergabe von that.method als Parameter nicht?
-
21-12-2019 - |
Frage
In einer Klasse, die eine Anfrage darstellt, versuche ich, sie mit Q-Versprechen zu verarbeiten und habe anschließend zwei einfache Handler, um das Ergebnis der Verarbeitung zu senden.Warum funktioniert das nicht:
Request.prototype.process = function() {
var that = this;
return that.getParameter('method')
.then(function(method) {
// ... Some processing
})
.then(that.replyOK)
.fail(that.replyError);
};
Aber das tut:
Request.prototype.process = function() {
var that = this;
return that.getParameter('method')
.then(function(method) {
// ... Some processing
})
.then(function(error) {
that.replyOK(error);
})
.fail(function(error) {
that.replyError(error);
});
};
Lösung
JavaScript hat größtenteils einen lexikalischen Gültigkeitsbereich.Dies bedeutet, dass in:
function foo(){
var that = this;
//...
}
Die darauf zugreifenden Variablen in den folgenden Zeilen von foo that
ist so eingestellt, wie Sie es erwarten.Wenn Sie Funktionen mit lokalen Definitionen an anderer Stelle übergeben, that
werden nicht in ihrer lexikalischen (variablen) Umgebung erfasst.
JavaScript verfügt auch über Dynamik this
, eine Methode this
wird durch das aktuell aufrufende Objekt bestimmt.Zum Beispiel:
var a = {
x:3,
getX:function(){ return this.x; }
};
var b = {x:5};
b.getX = a.getX;
b.getX(); // returns 5
a.getX(); // returns 3
a.getX.call(b); // set `this` explicitly with .call, returns 5
var x = a.getX;
x(); // global x or undefined.
Es ist möglich, es zu fixieren this
verwenden Function.prototype.bind
als solche:
Request.prototype.process = function() {
return this.getParameter('method')
.then(function(method) {
// ... Some processing
})
.then(this.replyOK.bind(this))
.fail(this.replyError.bind(this));
};
Oder in EcmaScript 6-Syntax (noch nicht im Knoten verfügbar, aber bald):
Request.prototype.process = () => { // arrow functions have lexical `this`
return that.getParameter('method')
.then(function(method) {
// ... Some processing
})
.then(this.replyOK)
.fail(this.replyError);
};