Skip to content

箭头函数与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 上下文。

仅用于培训和测试,通过使用本站代码内容随之而来的风险与本站无关。版权所有,未经授权请勿转载,保留一切权利。
ICP备案号:滇ICP备15009214号-13   公安网备:滇公网安备 53312302000061号