Search code examples
javascriptrhino

js - 'this' is undefined when calling method 'indirectly'


My goal is to call a function from a table of functions to generalize command handling (i.e indirectly). Unfortunately, this isundefined when called as such.

function Server() {
    this.sessions = {};

    server = this;
    this.handlers = {
        "dummy" : server.dummyCommandHandler,
    };
}

Server.prototype.dummyCommandHandler = function() {
    print (this.sessions);
}

Server.prototype.run = function ( command ) {
    print (this.sessions); // [Object object]
    this.handlers[command.name](); // prints 'undefined'
    this.dummyCommandHandler(); // prints '[Object object]'
}

s = new Server();
s.run({ "name": "dummy" });

This is my first time using javascript, and I thought I had the scoping down but apparently it is more complicated than it seems. Aliasing Server's this with the server variable didn't help (I thought perhaps this changes hands within the handlers object). What is the scope of this when the function is called indirectly?


Solution

  • The default behavior for this is that it refers to the function scope at the time it's invoked (see below). You can force the value of this by either using bind (MDN) or using arrow function syntax, which lexically-scopes your references to this to wherever you defined the function. This is the change I would make:

    "dummy" : server.dummyCommandHandler.bind(this),