Symptom:
You have created a
TypeScript class, and assigned a callback to an object implemented in Lambda expression (or have been suggested by Reshaper or IntelliJ to convert it to a lambda expression).
See the example below and what the problem is about to become much more clear.
The Issue
The issue is that the Lambda captures "this" in a different way than the anonymous function (). This is actually clearly documented under the
Arrow Functions section in the Mozilla MDN page.
But if you are like me it is much easier to understand by actually coding the situation.
The Explanation of The Example:
I have created a simple Main class in which a callback "
whatIsThis()" can be externally installed after the class has been instantiated. Then by calling
whatReallyIsThis(), it will in turn calls the installed
whatIsThis(). This is a fairly typical scenario, I would say.
If you are not aware of all of the implications of this, you would (and I have) thought that the class member property "s" should be accessible from within the callback in all of the scenarios.
The ones that works are;
- If the callback function is is a function() and not an arrow function like =>(). This will not work.
- Also, you can try this yourself, any attempt to pass "this" as main like Apply, Call or Bind to the lambda function will have no effect.
Lessons Learned
You should treat lambda as a whole new beast of function. It appears that they tried to fix the variable notion of "this" in lambda and it only captures "this" in the line of code where it was created. What throws you off is that you've learned about "this" with anonymous functions, and assumed it works the same. Be aware of this major difference!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
| class Main {
constructor(public s: string) {}
whatIsThis: () => void;
whatReallyIsThis() {
this.whatIsThis();
}
}
let main = new Main("works!");
console.log("Anonymouns func - this points to Main instance!");
main.whatIsThis = function() {
console.log("This " + this.s);
}
main.whatReallyIsThis(); // This works.
console.log("Using the Labmda - this does not work!");
main.whatIsThis = () => {
console.log("This s is " + this.s);
}
main.whatReallyIsThis(); // This s is undefined
console.log("Finally, what is this is all about");
let that = main;
exports.s = "in Global scope"; // Yup, it's in the Global!
main.whatIsThis = =>() {
console.log"Thi(s s is " + this.s);
console.log("That.s " + that.s);
}
main.whatReallyIsThis(); // This s is in Global scope, That.s works.
|