3.3 Arrow functions and the polymorphic this operator

Arrow functions expressions allow us to declare functions in a more compact way and have been designed to work particularly well when working with callbacks.

Getting Ready

All you need to be able to use arrow functions and the polymorphic this operator is an installation of TypeScript version 2.0 or higher.

How to do it…

It is common to encounter issues caused because the this operator is pointing to the wrong object when working with event handlers and callbacks:

class Form {
	
	constructor(){
		this.initializeEvents();
	}
	
	initializeEvents() {
		$('#submitBtn').on('click', function() {
			this.onSubmit(); // Error
		});
	}
	
	onSubmit() {
		// ...
	}
}

We can solve this issue by using an arrow function:

class Form {

	constructor(){
		this.initializeEvents();
	}
	
	initializeEvents() {
		$('#submitBtn').on('click', () => {
			this.onSubmit(); // OK
		});
	}
	
	onSubmit() {
		// ...
	}
}

How it works…

The this operator points to a class when it is accessed from one of the methods of the class but if we define a new function inside of one of its methods the this operator starts to point to the new function when inside it. Inside the event handler for the click event the this operator is not pointing to the Form class; it is pointing to the event handler function. This explains why the onSubmit method can not be found. In the second example we used an arrow function to declare the event handler. If we take a look to the generated JavaScript output, we will be able to see that the TypeScript compiler used a variable named _this to have reference to the Form class from the event handler:

Form.prototype.initializeEvents = function () {
  var _this = this;
  $('#submitBtn').on('click', function () {
    _this.onSubmit();
  });
};

There’s more…

TypeScript 1.7 introduces a new feature known as polymorphic this operator which allow us to use the this operator as the return type of the methods of a class:

class Binding {
	private _scope: string;
	
	inSingletonScope(): this {
	  this._scope = 'singleton';
	  return this;
	}
	
	inTransientScope(): this {
	  this._scope = "transient";
	  return this;
	}
	
	onActivation(cb: () => void) {
	  cb();
	}
}

This new feature makes it easier to write fluent interfaces:

const binding = new Binding().inSingletonScope().onActivation(() => {
    console.log('activating...');
  });

Source Code

Arrow functions and the polymorphic this operator

See also

Please refer to the Mozilla developer network to learn more about all the rules that are involved in the behavior of the this operator at https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this


Shiv Kushwaha

Author/Programmer