Why doesn't typescript use the "itself" trick?
I wrote the following TypeScript code:
class Person {
constructor(public firstname: string, public lastname:string){
}
public die(){
this.lastname += " RIP";
}
And this will compile for:
var Person = (function() {
function Person(firstname, lastname) {
this.firstname = firstname;
this.lastname = lastname;
}
Person.prototype.die = function () {
this.lastname += " RIP";
};
return Person;
})();
This is of course a valid way, but it will not work as expected in the following case:
function run(delegate){
delegate();
}
var person = new Person("guy", "dude");
run(person.die);
alert(person.lastname);
alert(lastname);
The expected warnings here will be "dude RIP" and then "undefined". However, the actual result will be "dude" and "undefined RIP". This is because this parameter works strangely in JS.
A common solution is to use your own variable through a closure and to abandon the prototype mechanism, i.e.
var Person = (function() {
function Person(firstname, lastname) {
var self = this;
self.firstname = firstname;
self.lastname = lastname;
self.die = function() {
self.lastname += " RIP";
}
}
return Person;
})();
Which will work as expected. What is the advantage of this particular way of compiling the code? Has TypeScript been able to leave this piece of unintuitive code behind?
source to share
You need to restructure your code a bit to use the template _this = this
:
class Person {
constructor(public firstName: String, public lastName: String) {
}
die = () => {
this.lastName += "dead"
}
}
becomes:
var Person = (function () {
function Person(firstName, lastName) {
var _this = this;
this.firstName = firstName;
this.lastName = lastName;
this.die = function () {
_this.lastName += "dead";
};
}
return Person;
})();
The key part is that you need to put the die function on the object, not the prototype, which forces it to be used _this = this
.
source to share
You must use the arrow function syntax when you want to capture it. I think it would be better to use this when creating a delegate instead of creating a class.
The only change that would need to be made:
run(()=>person.die());
This allows you to capture this for any function, no matter how it was defined.
source to share