`this` context lost in Javascript/Typescript
In Javascript, the context of this
is often “lost”, but what it’s actually doing is indeed referencing the current scope it’s in at runtime. this
Javascript behavior is a big reason why people dislike the language so much. Hater’s gon’ hate! Typescript offers an easy solution to this which compiles into the Javascript you would have had to written to resolve this.
Example
function Foo() {
this.message = "Howdy";
this.shout = function () {
alert(this.message);
};
document.addEventListener('click', this.shout, false);
}
var foo = new Foo();
In this example we would expect clicking the document would alert “Howdy” but instead it alerts undefined
… ?!!!
…the same happens in Typescript:
class Foo {
message: string = "Howdy";
shout(){
alert(this.message);
}
constructor(){
document.addEventListener('click', this.shout, false);
}
}
let foo = new Foo();
The context of this
is not what we want it to be!
Why?
The this
within the shout
function is referencing the document
rather than the desired instance of Foo
because shout
is being executed within the document
scope:
document.addEventListener('click', this.shout, false);
The fix
Typescript has given us ‘arrow function’ syntax to fix this:
class Foo {
message: string = "Howdy";
shout = () => {
alert(this.message);
}
constructor(){
document.addEventListener('click', this.shout, false);
}
}
Syntax-wise all that has changed is function()
to () =>
. In Javascript
you would have had to do this (and infact this is what the above compiles into):
function Foo() {
var _this = this;
this.message = "Howdy";
this.shout = function() {
alert(_this.message);
};
document.addEventListener('click', this.shout, false);
}
Storing a reference to this
at the root of the class/function means there will be no confusion of what this
it’s suppose to be. Another popular name for _this
is/was that
.
With Typescript, it does this for you at compile time and you can use this
with confidence… ?!!!