The this
keyword is highly contextual. If a method is called by an event, this
will be the object that is the event target, for example.
You can get around this problem by shimmying this
into a variable, or by using the JavaScript call
(or apply
) methods to bind the scope of this
.
Short example... here is the premise:
class MyClass {
constructor(private myProp: string) {
}
myMethod() {
alert(this.myProp);
}
}
var myClass = new MyClass('Test');
// 'Test'
myClass.myMethod();
// undefined
window.setTimeout(myClass.myMethod, 1000);
Solution One - Arrow Syntax
In TypeScript the arrow syntax will shimmy this
into a variable called _this
automatically for you and substitute usages inside the arrow function... So this will solve the undefined
issue above and instead alert Test
.
class MyClass {
constructor(private myProp: string) {
}
public myMethod = () => {
alert(this.myProp);
}
}
Solution Two - Call Method
You can use the call
method to replace the contextual this
with any object you like, in the example below we reset it to be the myClass
instance.
This works whether you are writing TypeScript or plain JavaScript... whereas the first solution is really a TypeScript solution.
window.setTimeout(function() { myClass.myMethod.call(myClass) }, 1000);
Or to be shorter (to be clear, the use of the arrow function here has nothing to do with scope - it is just a shorter syntax arrow functions only affect scope if you have this
inside of them):
window.setTimeout(() => myClass.myMethod.call(myClass), 1000);