Reputation: 637
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
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
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