When working with TypeScript, it's important to understand some of the key differences between named and fat arrow functions. Let's have a look at a basic class with one of each type of function defined, and also the resulting ES5 that TypeScript transpiles to for a better understanding.Here is a sample TypeScript class with the two different types of functions.

For the purpose of this post, we'll concentrate on (2) main aspects of the code

Where the method is created on the object, and the resulting performance impact

How the thiskeyword behaves

It's important to understand the differences because there is a performance impact. Notice how the named function on the class is created and attached on the object's prototype. In this manner, the method is stored in memory only one time, as objects created from the same constructor point to a single prototype object. This is the more memory efficient implementation.

Now inspect the fat arrow's function in the ES5 code. Because the method is declared and created in the object's constructor (instance member), it will be declared again per each new instance of this type of object created. This has a memory and performance overhead. As a note, this is the identical resulting behavior to explicitly creating methods within the class constructor in TypeScript.

At this point we might be thinking, "Well that's enough let's just use named functions which will be declared on the object's prototype and be done with it!" There is more than meets the eye and the fat arrow function is quite useful. One of the main advantages is that fat arrow functions lexically capture the context of this in TypeScript. This is critically important in functions that contain callbacks or where re-assignment of instance variables might occur. The former use case is one that we run into often with observable callbacks in say Angular components. You may have run into issues with the this keyword and noticed it wasn't the correct context. The issue is if not using the fat arrow syntax, the context of the thiskeyword will be undefined. If strict mode isn't enabled, the context of thiswill be of the window object. If you look in the ES5 tanspiled code, you'll notice thisis captured from outside the function body allowing our context to be captured correctly.

var _this = this;

Let's look at the console output from the original code above. Notice in the setTimeout call the use of this. However in this instance it's not the proper context resulting in undefined when accessed.

The fix is to update the callback to use the fat arrow syntax which will capture the correct context of this.

In a TypeScript project with the default configuration of "noImplicitThis": true set in the tsconfig.json file, you'll actually be warned in the IDE of this scenario, " 'this' implicitly has type 'any' because it does not have a type annotation." This would be an indication you need to use the fat arrow function instead.

There are other use cases beyond the ones I'm mentioning here today in regards to the behavior of this with inheritance and calling the parent class as well as other differences. However these are two key areas that should be understood, as I see the usage flip-flop without intent, and developers should be aware of the performance and behavior differences and create the correct type where appropriate. They have separate purposes, so I'm not a fan of just one or the other. Using only fat arrow functions have their performance impact, but shouldn't be avoided all together as they are instrumental on capturing the correct context of thiswhen needed.

Related Postings:

0
comments:

Post a Comment

About Me

I am a Magenic Practice Lead that is an advocate of web client and Microsoft .NET technologies both professionally and personally. I enjoy the challenge and creativity behind software engineering, and hope during this process to extract some of my thoughts and ideas in order to give back to others in the community through public speaking and here on this blog.