所有 3 个版本之间都存在差异。这种差异体现在 3 个方面:
- Who is
this
在运行时
- 函数被分配的地方
- 是什么类型的
this
在打字稿中。
让我们从它们工作的地方开始。考虑这个类,它有一个类字段:
class Greeter {
constructor(private x: string) {
}
greet() {
console.log('greet1', this.x);
}
greet2 = () => {
console.log('greet2', this.x);
}
greet3 = function () {
// this is typed as any
console.log('greet3', this.x);
}
}
let bla = new Greeter(" me");
对于此类,所有 3 个函数调用都将按预期打印:'greet* me'
当调用时bla
bla.greet()
bla.greet2()
bla.greet3()
运行时这是谁
箭头函数捕获this
从声明上下文来看,所以this
in greet2
始终保证是创建此函数的类实例。其他版本(方法和函数)没有做出这样的保证。
因此,在这段代码中,并非所有 3 个都打印相同的文本:
function call(fn: () => void) {
fn();
}
call(bla.greet) // greet1 undefined
call(bla.greet2) //greet2 me
call(bla.greet3) // greet3 undefined
当将函数作为事件处理程序传递给另一个组件时,这一点尤其重要。
函数被分配的地方
类方法(例如greet
)被分配在原型上,字段初始化(例如greet2
and greet3
) 在构造函数中赋值。这意味着greet2
and greet3
将具有更大的内存占用,因为它们每次都需要分配新的闭包Greeter
被实例化。
typescript 中的 this 类型是什么?
打字稿将输入this
作为一个例子Greeter
在这两个方法中(greet
)和箭头函数(greet2
)但会输入this
与任何在greet3
。如果您尝试使用,这将导致错误this
in greet3
under noImplictAny
何时使用它们
如果此函数不会作为事件处理程序传递给另一个组件,请使用方法语法(除非您使用bind
或其他东西来确保this
仍然是类的实例)
当您的函数将传递给其他组件并且您需要访问时,请使用箭头函数语法this
函数内部。
实在想不出一个好的用例,通常会避免。