duper51
duper51

Reputation: 780

nodejs - Which "this" is this?

So this is an awkward question to ask, but I'm learning NodeJS and I have a question. In Java when I call a method from an object, the this instance remains the same (as in this example).

private Test inst;
public Test() {
    inst = this;
    this.myFunction();
}

private void myFunction() {
    System.out.println(inst == this);
}

This returns true (in theory, that's code off the top of my head). However, in NodeJS when I attempt to do something similar it fails.

var MyObject = function () {
    this.other = new OtherObject();
    this.other.on("error", this.onError);
    console.log(this); //This returns the MyObject object
}

MyObject.prototype.onError = function (e) {
    console.log(this); //This returns the OtherObject object, where I thought it would return the MyObject object.
}

My question is why is this so, and if this is being done incorrectly on my part, how may I correctly reference other variables in the MyObject instance from the onError method?

Upvotes: 6

Views: 167

Answers (2)

Vladimir
Vladimir

Reputation: 342

There is simpler way - you can use bind function.

var EventEmitter = require('events').EventEmitter;

var MyObject = function () {
    this.other = new EventEmitter();
    this.other.on("error", this.onError.bind(this));
    console.log(1, this instanceof MyObject); // 1, true
};

MyObject.prototype.onError = function (e) {
    console.log(2, this instanceof MyObject); // 2, true
};

MyObject.prototype.callError = function (e) {
    console.log(3, this instanceof MyObject); // 3, true
    this.other.emit('error', e);
};

var mo = new MyObject();

mo.callError(new Error(1));

Demo

Upvotes: 0

B3rn475
B3rn475

Reputation: 1057

In JavaScript "methods" are just functions that part of an object.

If you do

var obj = new MyObject();
obj.onError();

The this in onError will be the obj object (because it is the object it is invoked from)

Instead in you case you are passing this.onError to the EventEmitter it will call that function with the EventEmitter (OtherObject) as this.

To avoid that problem use an anonimous function.

var MyObject = function () {
    var self = this;
    this.other = new OtherObject();
    this.other.on("error", function (e) { self.onError(e); });
}

In this way you are binding this back to the object you expect

Upvotes: 6

Related Questions