1

Possible Duplicate:
JavaScript “this” keyword

I am a bit confused about the callbacks used for EventEmitter 's in node.js.

var events = require("events");

function myObject() {
    this.name = "Test Object";
    this.x = 99;
    this.y = 100;
}

myObject.prototype = new events.EventEmitter();

var myobject = new myObject();

myobject.addListener('dbg1', function() {
    console.log("this.name = " + this.name);    //this.name gives the name not undefined
    console.log("myobject.name = " + myobject.name);        //so does this 
});

myobject.emit('dbg1');

Why is this inside the callback referring to myobject? The closure for the callback function is the global scope in this code, am I right?

Community
  • 1
  • 1
Andariel
  • 133
  • 4
  • 9

2 Answers2

6

Scope is irrelevant for determining the value of this, that comes from the context. That is determined by how the function is called. The events module you load will call it in the context of myobject.

The relevant code is:

listener.apply(this, args);

The first argument of the apply method is the context to use for calling the function (listener). You can trace it back to the object from there.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • I see. So, node too calls the callback with by `apply` -ing it on the object? I am a newbie at node as well as javascript, so I guess this is the standard way events are implemented in every api? – Andariel Jan 13 '13 at 18:23
  • It's the event library that does not, not node itself. There are various ways an event api could be implemented, almost everything will make `this` the object to which the event is bound though. – Quentin Jan 13 '13 at 19:13
1

This is the same for most of the node codebase. There was a small discussion about this a long time ago, and the consensus was that .call(this) entails too much overhead and was really ugly/annoying to put everywhere. So in other words, don't ever assume this is what you think.

edit: Nevermind, EventEmitter doesn't specifically apply in this case and I completely misread your question.

chjj
  • 14,322
  • 3
  • 32
  • 24
  • 1
    I strongly suspect that it's safe to assume that EventEmitter will always arrange for `this` to refer to the object that's the target of an event. – Pointy Jan 13 '13 at 18:13
  • Well according to the code posted in Quentin's answer it definitely does. – Pointy Jan 13 '13 at 18:22
  • @Pointy, yeah, I misread the question as a case of "`this` doesn't equal my object". My answer is very irrelevant (I was pointing out there are a lot of places in node and node modules where callbacks won't be invoked with a context). You're right though, EventEmitter::emit is not one of them. – chjj Jan 13 '13 at 18:31