Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't passing that.method as a parameter work?

In a class that represent a request, I try to process it with Q promises and after that, have two simple handlers to send the result of the processing. Why doesn't this work:

Request.prototype.process = function() {
    var that = this;
    return that.getParameter('method')
    .then(function(method) {
        // ... Some processing
    })
    .then(that.replyOK)
    .fail(that.replyError);
};

But this does:

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);
    });
};
like image 244
Max Yankov Avatar asked Jan 28 '26 19:01

Max Yankov


1 Answers

JavaScript is mostly lexically scoped. This means that in:

 function foo(){
     var that = this;
     //...
 }

The variables accessing that in the following lines of foo that is set to what you expect it to. If you pass functions with locals defines elsewhere, that won't be captured in their lexical (variable) environment.

JavaScript also has dynamic this , a method's this is determined by the currently calling object. For example:

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.

It's possible to fixate this using Function.prototype.bind as such:

Request.prototype.process = function() {
    return this.getParameter('method')
    .then(function(method) {
        // ... Some processing
    })
    .then(this.replyOK.bind(this))
    .fail(this.replyError.bind(this));
};

Or, in EcmaScript 6 syntax (not available in node yet, but soon):

Request.prototype.process = () => { // arrow functions have lexical `this` 
    return that.getParameter('method')
    .then(function(method) {
        // ... Some processing
    })
    .then(this.replyOK)
    .fail(this.replyError);
};
like image 122
Benjamin Gruenbaum Avatar answered Jan 31 '26 08:01

Benjamin Gruenbaum



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!