Reputation: 7264
I have this piece of Typescript code:
constructor($triggerHref: JQuery) {
// stuff...
var _this = this;
$(document).on("click",$triggerHref.selector,e=>{
e.preventDefault();
var target = $(e.srcElement).attr("data-pcc-sort-trigger");
if (target == _this.active)
_this.load(target, !_this.isDescending);
else _this.load(target, false);
});
}
If I remove the var _this = this;
line and just use this
inside the event handler, the generated js code looks reasonably the same (it generates the _this anyway), yet for some reason this.active
and this.load()
are undefined.
My understanding of TS's scoping was that ()=>{}
methods keep the this
from their parents, and only function(){}
methods work like usual JS methods.
So why is this one not working for me?
Upvotes: 4
Views: 711
Reputation: 8156
As you have already noticed, lambda functions capture this
at the time the lambda function is defined. This can lead to wierd results (also there are a few bugs around var _this = this
), although most of these seems to be fixed.
The whole language construct seems to be for the purpose of cheating JavaScript scoping (this
is the object that the function is called on).
As for the weirdness you explained (this.active and _this.active behaving differently), there is no explanation inside the scope of the question.
The generated JavaScript (as you have stated) should be (nearly) the same. Well apart from writing var _this = this;
leading to _this
defined more than once in the same scope and breaking javascript validity. This is a problem around TypeScript lambdas. Never define _this
in TS as it is reserved for some purposes (and not checked if it's free).
And there is no magic in TypeScript. What gets executed is the JavaScript it generates. Check if something overwrites _this
in the same scope (which would be easy to spot since the scope of var _this
is the scope of the constructor function, also var
hides the variables with the same name coming from an outer scope, so it should be inside the constructor).
I avoid using lambda expressions in TypeScript for now. Using simple anonym functions instead, does not require you to restructure any of your code. Saving this
to an other variable can be considered ugly yes, but you can work around it by using $.proxy() for example. This way you can even write a regex replace to change your lambdas to $.proxy(). For now.
So all in all I would need to debug the generated JS to spot the error since your code should be syntactically fine. It seems to me that the TypeScript compiler needs some rethinking around this (I hope some TS enthusiasts will differ and teach me how it is properly done, as I'm not agains TS, on the contrary).
I'm pretty sure @RyanCavanaugh would be able to prepare a better answer.
Upvotes: 1
Reputation: 700152
The lambda expression generates a function expression, so the same rules for scope applies to a lambda expression as a function expression.
Example:
var x = e => {};
genrates this Javascript code:
var x = function (e) {
};
Upvotes: 0