Reputation: 800
I'm new to JS, so I have this newbie question about right way to bind references. For example, I have this line of code in TypeScript:
this.socket.on('new_task').subscribe(this.newTask);
...
newTask(data) {
this.logEvent('new_task', data);
this.audio.playNewJob();
}
logEvent(event: string, data) {
console.log(this.TAG + event + ' triggered with received data: ' + JSON.stringify(data));
}
If I will try run this, I will get:
TypeError: this.logEvent is not a function
If I will change to:
this.socket.on('new_task').subscribe((data) => this.newTask(data));
Everything will work fine but it looks like a bad way to use JS and TS features. What is a recommended practice in this case?
Upvotes: 0
Views: 648
Reputation: 123891
I'd face to this issue with property, instead of method
. I.e. we can declare kind of same functionality with "property syntax" .. where property is a function (newTask
below is method, newTaskAsProperty
is more property-ish)
class MyClass {
newTask(data) {
this.logEvent('new_task', data);
this.audio.playNewJob();
}
newTaskAsProperty = (data) =>{
this.logEvent('new_task', data);
this.audio.playNewJob();
}
...
what is interesting, is what would be the transpiled result:
var MyClass = (function () {
function MyClass() {
var _this = this;
this.newTaskAsProperty = function (data) {
_this.logEvent('new_task', data);
_this.audio.playNewJob();
};
}
MyClass.prototype.newTask = function (data) {
this.logEvent('new_task', data);
this.audio.playNewJob();
};
So, the property approach (newTaskAsProperty = (data) =>{}
) is applied in constructor, to the instance, not to prototype. And that is, why using is as a delegate will work as expected
// not working
// this.socket.on('new_task').subscribe(this.newTask);
// working
this.socket.on('new_task').subscribe(this.newTaskAsProperty);
The only downside is - it is not a method, i.e. cannot be overriden.
As a workaround, we can simply do call a real method inside of that - if needed, and that method would have this
properly set and could be overriden...
Upvotes: 0
Reputation: 13379
The issue is how "this" is bound, it's done at execution time so when the logEvent function is invoked this refers to the global object which doesn't have that function. Your second example is fine, in that case this is bound when the arrow function is defined, an alternative is to store a references to this and call the function from that but personally I prefer the arrow function approach. Beware that not everyone agrees with this but I'm used to arrow functions from c# and I think if you understand the differences they read easier as well as having a simpler way of reasoning about this.
Upvotes: 2