- Learning TypeScript 2.x
- Remo H. Jansen
- 560字
- 2025-04-04 17:02:05
Arrow functions
In TypeScript, we can declare a function using a function expression or an arrow function. An arrow function has a shorter syntax than a function expression, and lexically binds the value of the this operator.
The this operator behaves a little differently in TypeScript and JavaScript compared to other popular programming languages. When we define a class in TypeScript, we can use the this operator to refer to the class. Let's look at an example:
class Person { private _name: string; constructor(name: string) { this._name = name; } public greet() { console.log(`Hi! My name is ${this._name}`); } } let person = new Person("Remo"); person.greet(); // "Hi! My name is Remo"
We have defined a Person class that contains a property of a string type called name. The class has a constructor and a greet method. We have created an instance named person and invoked the greet method, which uses the this operator internally to access the _name property. Inside the greet method, the this operator points to the object that encloses the greet method.
We must be careful when using the this operator, because in some scenarios it can point to the wrong value. Let's add an extra method to the previous example:
class Person { private _name: string; constructor(name: string) { this._name = name; } public greet() { alert(`Hi! My name is ${this._name}`); } public greetDelay(time: number) { setTimeout(function() { alert(`Hi! My name is ${this._name}`); // Error }, time); } }
In the greetDelay method, we perform an almost identical operation to the one performed by the greet method. This time, the function takes a parameter named time, which is used to delay the greet message.
To delay a message, we use the setTimeout function and a callback. As soon as we define an anonymous function (the callback), the this keyword changes its value and starts pointing to the anonymous function, which explains why the TypeScript compiler will throw an error.
As mentioned, an arrow function expression lexically binds the value of the this operator. This means that it allows us to add a function without altering the value of the this operator. Let's replace the function expression from the previous example with an arrow function:
class Person { private _name: string; constructor(name: string) { this._name = name; } public greet() { alert(`Hi! My name is ${this._name}`); } public greetDelay(time: number) { setTimeout(() => { alert(`Hi! My name is ${this._name}`); // OK }, time); } } let person = new Person("Remo"); person.greet(); // "Hi! My name is Remo" person.greetDelay(1000); // "Hi! My name is Remo"
By using an arrow function, we can ensure that the this operator still points to the Person instance and not to the setTimeout callback. If we execute the greetDelay function, the name property will be displayed as expected.
The following piece of code is generated by the TypeScript compiler. When compiling an arrow function, the TypeScript compiler will generate an alias for the this operator named _this. The alias is used to ensure that the this operator points to the right object:
Person.prototype.greetDelay = function (time) { var _this = this; setTimeout(function () { alert("Hi! My name is " + _this._name); }, time); };