Sunday, June 15, 2014

Managing the JavaScript “this” keyword in TypeScript

Which This?

If you’ve worked with JavaScript for while, you’ve likely been made aware of the unique power and confusion that comes with the “this” keyword. We’ve been using TypeScript in some of the single-page applications we’ve been working on, and it has a helpful syntax to help you manage the “this” keyword.


Consider the following TypeScript:

1 $('div').each(function (index: number, element: Element) { 2 $(this).find('p').each(function (index: number, element: Element) { 3 $(this).addClass('selected'); 4 }); 5 }); 6

In each of these anonymous functions (lines 1 and 2 respectively) the keyword “this” (on lines 2 and 3) refers to the respective element that’s being iterated over (each div in the first function, each p in the second function.

However, using the => operator (sometimes called the “rocket ship” operator) when declaring the an anonymous function, changes the context of “this”.

If we rewrite the TypeScript to be:

1 $('div').each(function (index: number, element: Element) { 2 $(this).find('p').each((index: number, element: Element) => { 3 $(this).addClass('selected'); 4 }); 5 }); 6

The second function (that gets applied to each p tag) now has a “this” that refers to the parent scope. The “this” keyword now refers to a div. This is because the resulting JavaScript looks like:

1 $('div').each(function (index, element) { 2 var _this = this; 3 $(this).find('p').each(function (index, element) { 4 $(_this).addClass('selected'); 5 }); 6 }); 7

Notice how the scope prior to the second (rocket shipped) anonymous function becomes accessible inside the anonymous function. This can also be used multiple times. E.G. If the parent TypeScript function had also been authored with the rocket ship syntax (() => {}) then the “this” keyword in all scopes would refer to the owner of the first function (the containing class or window object in this case).

Wrapping Up

As applications are becoming increasingly functional, the context in which anonymous functions are running becomes a more important tool for writing code. Knowing about some of TypeScrpt’s syntactic sugar helps us manage the “this” keyword without dropping down into JavaScript’s call, bind, and apply.