Есть различия между всеми 3 версиями.Это различие в 3 областях:
- Кто
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
в greet2
всегда гарантированно будет экземпляром класса, который создал эту функцию.Другие версии (метод и функция) не дают таких гарантий.
Так что в этом коде не все 3 печатают один и тот же текст:
function call(fn: () => void) {
fn();
}
call(bla.greet) // greet1 undefined
call(bla.greet2) //greet2 me
call(bla.greet3) // greet3 undefined
Это особенно важно при передаче функции какобработчик событий для другого компонента.
Если функция назначена
Методы класса (например, greet
) назначаются в прототипе, инициализация поля (например,greet2
и greet3
) назначаются в конструкторе.Это означает, что greet2
и greet3
будут иметь больший объем памяти, поскольку они требуют выделения нового замыкания каждый раз, когда создается экземпляр Greeter
.
Какого типа это в машинописи.
Typescript будет печатать this
как экземпляр Greeter
как в методе (greet
), так и в функции стрелки (greet2
), но будет печатать this
как любой вgreet3
.Это приведет к ошибке, если вы попытаетесь использовать this
в greet3
в noImplictAny
Когда их использовать
Используйте синтаксис метода, если эта функция не будет передана в качестве обработчика события другому компоненту (если только вы не используете bind
или что-то еще, чтобы this
оставался экземпляром класса)
Используйте синтаксис функции стрелки, когда ваша функция будет передана другим компонентам, и вам нужен доступ к this
внутри функции.
Не могу придумать хороший вариант использованиядля этого вообще избегайте.