Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I access the other this in a TypeScript lambda?

Tags:

typescript

In typescript, I can write something like this:

$('#something').fadeOut(400, (): void => {     this.invokeAnotherMethod(); }); 

When compiled, TypeScript automatically makes sure this points to my class instead of the enclosed function:

var _this = this; $('#something').fadeOut(400, function() {     _this.invokeAnotherMethod(); }); 

However, what about when I need to access the real this instead of the outer _this? Is there syntax to reference it? For example, how could I write code that would compile to the following:

var _this = this; $('#something').fadeOut(400, function() {     $(this).data('specialhide', true);     _this.invokeAnotherMethod(); }); 

Is it possible?

like image 639
danludwig Avatar asked Dec 18 '12 13:12

danludwig


People also ask

Can you use TypeScript in lambda function?

You can use the Node. js runtime to run TypeScript code in AWS Lambda.

Is it possible to access variables from the outside of a lambda expression?

The rule is that a lambda expression can only access local variables from an enclosing scope that are effectively final.

Which of these is a valid arrow lambda function in TypeScript?

ES6 version of TypeScript provides an arrow function which is the shorthand syntax for defining the anonymous function, i.e., for function expressions. It omits the function keyword. We can call it fat arrow (because -> is a thin arrow and => is a "fat" arrow). It is also called a Lambda function.

What does TypeScript use for anonymous functions?

TypeScript Anonymous Functions are functions that are not bound to an identifier i.e., anonymous functions do not have name of the function. Anonymous functions are used as inline functions. These are used when the function is used only once and does not require a name. The best example is a callback function.


2 Answers

You would need to avoid the fat-arrow syntax to do this as you don't want to preserve the lexical scope of this.

var _me = this; $('#something').fadeOut(400, function () {     _me.invokeAnotherMethod();     $(this).data('specialhide', true); }); 

In this example I have used _me rather than _this to avoid any collisions with TypeScript generated variables. I have also avoided self, to avoid confusion with window.self (thanks RockResolve).

The Why!

The ECMAScript 6 specification features Arrow Function Definitions - it is where the TypeScript language has taken this feature from. When TypeScript targets ECMAScript 6 in the future, it will leave in the () => syntax - so they can't make it work with both contexts of this without breaking future compatibility.

Even though you could imagine how they could change the TypeScript compiler to make both _this and this available in ECMAScript 3 or 5, it would actually become a problem in version 6.

like image 121
Fenton Avatar answered Oct 07 '22 23:10

Fenton


I figured a way out, as described here in my answer at: How can I preserve lexical scope in TypeScript with a callback function

This is a nicer way of achieving the closure that Steve Fenton did in his answer. I prefer it because the method signature documents usage.

Basically, use a method like so:

fadeOutLambda(outerThis: YourClass): {(d: number, i: number): number}{     return function(d: number, i: number){         // Put your "fadeOut" logic here         // refer to "this" to mean the dynamically scoped "this"         // refer to "outerThis" to refer to the class instance         alert(outerThis); // lexically scoped class instance         alert(this); // dynamically scoped context caller         return 999;     } } 
like image 29
Eric Avatar answered Oct 08 '22 00:10

Eric