Dave
Dave

Reputation: 637

why is this private method in a constructor?

I'm a bit puzzled by this coding pattern I've run into even though I've been studying up on 'this.' The following (simplified) code shows the pattern:

var MyConstructor = function MyConstructor() {
    this._handlers = {
        action: this.handleAction.bind(this)
    };
};

MyConstructor.prototype.start = function(someObj) {
    this.someObj.on(’some event’, this._handlers.action);  //<--here
}

MyConstructor.prototype.handleAction = function() {
    //do stuff
}

module.exports = MyConstructor;

My question is, why is the private method in the constructor required? Is this pattern avoid some common problem? Could the line commented //<--here simply be:

this.someObj.on(’some event’, this.handleAction);

Upvotes: 3

Views: 130

Answers (2)

Tibos
Tibos

Reputation: 27833

The difference between the following lines

this.someObj.on(’some event’, this.handleAction.bind(this));
this.someObj.on(’some event’, this.handleAction);

... is that the first handleAction will run with this being the instance of MyConstructor, while the second will run in whatever context the event handling mechanism decides. If it is something like this, it will run with this being the global object:

function on (a, callback) {
  callback(); // callback is run with this as the global object 
              // UNLESS it was bound to something else
}

The 'private' _handlers property is just an object that holds references to callbacks bound to the instance. If you were to call bind twice, two functions would be created. The _handlers property makes it so that a single bound function is created which can be used as a handler for any number of events.

Upvotes: 2

lonesomeday
lonesomeday

Reputation: 237985

No, they are different. The difference is in context, which means the value of this within the function.

this.handleAction passes the function to on without any context. There is no value of this specified. The value will be determined when the function is executed. It is very likely that the value will not be the a MyConstructor object, so this.start, for instance, will not refer to the right object, or indeed perhaps any object at all.

The solution is to bind context. This sets the context forever, so this will always refer to the right value. You see this line of code:

action: this.handleAction.bind(this)

This means that, when the code later refers to this._handlers.action, it will be sending the function to on with the appropriate context, so this will always point to the correct value.

Upvotes: 3

Related Questions