Appearance
箭头函数与this
在Javascript的世界里,箭头函数在ES6中作为一种新的函数定义方式,它提供了一种更简洁的方法来写函数。箭头函数使用“=>”符号来定义函数,这个符号看起来就像是一个箭头,因此得名“箭头函数”。
总的特征就是,一个语法糖,省去了花括号,并解决了一个核心的问题,就是this的指向问题。从而省略了var that = this;
的写法。
js
const functionName = (parameters) => expression;
箭头函数有几个特点:
- 没有自己的 this、arguments、super 或 new.target。这些值由外围的最近一层非箭头函数决定。
- 不能用作构造函数,也就是说,不能使用 new 关键字调用。
- 没有 prototype 属性。
- 不适合定义对象方法,也不应该用作事件监听函数。 Typescript的箭头函数,与JS存在差异,但可以认为是TS的进一步优化。在 TypeScript 中,箭头函数(Arrow Functions)与 JavaScript 中的箭头函数在语法上基本一致,但 TypeScript 提供了类型注解的功能,这可以增加代码的可读性和安全性。 TypeScript 中的箭头函数可以带有参数和返回值的类型注解,这样可以帮助开发者更清晰地理解函数期望的输入和输出,并在编译时进行类型检查。 下面是一个 TypeScript 箭头函数的示例,其中包含了参数和返回值的类型注解:
ts
const greet: (name: string) => string = (name: string) => {
return `Hello, ${name}!`;
};
const message = greet("Alice"); // "Hello, Alice!"
甚至如果你想要一个更简洁的箭头函数,并且函数体只有一条语句,你可以省略花括号:
ts
const double: (x: number) => number = x => x * 2;
const doubledValue = double(4); // 8
但需注意,这种省略花括号的方式只适用于函数体只有一条语句的情况,如果函数体有多条语句,则必须保留花括号。并且在你需要对照上面的原箭头函数,理解箭头函数的构造 ouble 是一个简单的箭头函数,它接受一个 number 类型的参数 x,并返回 x 的两倍。函数的类型被注解为 (x: number) => number,意味着它接受一个数字并返回一个数字。 箭头函数在 TypeScript 中非常有用,特别是当你需要快速定义简短的、不需要自己 this 上下文的函数时。同时,通过类型注解,你可以增加代码的可读性和健壮性。
比较下来,你已经很明确的了解了箭头函数的语法和作用,以及如何使用 TypeScript 中的箭头函数。且知道和JS的差异。
js
/// 如果使用JS实现
const (x) => number = x => x * 2;
const doubledValue = double(4); // 8
this的指向
JavaScript里,this的值在函数被调用的时候才会指定。 这是个既强大又灵活的特点,但是你需要花点时间弄清楚函数调用的上下文是什么。 但众所周知,这不是一件很简单的事,尤其是在返回一个函数或将函数当做参数传递的时候。
注意箭头函数不绑定自己的 this,它们会捕获其所在上下文的 this 值。这与传统的函数表达式或函数声明不同,后者在调用时会根据自己的调用方式(例如,作为对象方法调用、直接调用或通过 call/apply/bind 调用)来决定 this 的值。
ts
class MyClass {
constructor(private name: string) {}
// 传统函数
regularFunction() {
console.log(this.name); // 正确输出类实例的name属性
// 使用传统函数定义的内部函数,这里的this不会指向MyClass实例
function innerFunction() {
console.log(this.name); // 输出undefined,因为this不指向MyClass实例
}
innerFunction();
// 使用箭头函数定义的内部函数,这里的this会捕获外部函数的this值
const innerArrowFunction = () => {
console.log(this.name); // 正确输出类实例的name属性
}
innerArrowFunction();
}
// 箭头函数
arrowFunction = () => {
console.log(this.name); // 正确输出类实例的name属性
// 在箭头函数内部,this仍然指向MyClass实例
const innerArrowFunction = () => {
console.log(this.name); // 正确输出类实例的name属性
}
innerArrowFunction();
}
}
const instance = new MyClass("MyClassInstance");
instance.regularFunction(); // 输出:MyClassInstance, undefined, MyClassInstance
instance.arrowFunction(); // 输出:MyClassInstance, MyClassInstance
在这个例子中,MyClass 类有两个方法:regularFunction 和 arrowFunction。regularFunction 是一个传统函数,而 arrowFunction 是一个箭头函数。当我们在 regularFunction 内部定义一个传统函数 innerFunction 时,this 不再指向 MyClass 的实例,而是指向全局对象(在浏览器中是 window)或 undefined(在严格模式下)。然而,在 regularFunction 内部定义的箭头函数 innerArrowFunction 会捕获外部函数的 this,因此它仍然指向 MyClass 的实例。
ts
// 箭头函数自动绑定上下文
person = {
name: "Alice",
sayHello: () {
setTimeout(() => {
console.log(`Hello, my name is ${.name}.`);
}, 1000);
}
};
person.sayHello(); // 输出:Hello, my name is Alice.
另一方面,arrowFunction 作为一个箭头函数,它自然地捕获了定义它时的 this 上下文,即 MyClass 的实例。因此,在 arrowFunction 内部定义的任何箭头函数也将继承这个 this 上下文。