Могу ли я получить доступ к другому в lambda TypeScript?
В typescript я могу написать что-то вроде этого:
$('#something').fadeOut(400, (): void => {
this.invokeAnotherMethod();
});
При компиляции TypeScript автоматически указывает, что это указывает на мой класс, а не на закрытую функцию:
var _this = this;
$('#something').fadeOut(400, function() {
_this.invokeAnotherMethod();
});
Однако, как насчет того, когда мне нужно получить доступ к реальному, а не внешнему _this? Есть ли синтаксис для ссылки на него? Например, как я мог написать код, который бы скомпилировал следующее:
var _this = this;
$('#something').fadeOut(400, function() {
$(this).data('specialhide', true);
_this.invokeAnotherMethod();
});
Возможно ли это?
Ответы
Ответ 1
Вам нужно будет избежать синтаксиса толстой стрелки, чтобы сделать это, так как вы не хотите сохранять лексическую область this
.
var _me = this;
$('#something').fadeOut(400, function () {
_me.invokeAnotherMethod();
$(this).data('specialhide', true);
});
В этом примере я использовал _me
, а не _this
, чтобы избежать столкновений с TypeScript сгенерированными переменными. Я также избегал self
, чтобы избежать путаницы с window.self
(спасибо RockResolve).
The Why!
В спецификации ECMAScript 6 указаны определения функции стрелки - это язык, на котором язык TypeScript использовал эту функцию. Когда TypeScript будет нацелен на ECMAScript 6 в будущем, он останется в синтаксисе () =>
, поэтому они не смогут заставить его работать с обоими контекстами this
, не нарушая будущей совместимости.
Даже если бы вы могли представить, как они могли бы сменить компилятор TypeScript, чтобы сделать как _this
, так и this
доступными в ECMAScript 3 или 5, это фактически станет проблемой в версии 6.
Ответ 2
Я понял выход, как описано здесь в моем ответе:
Как сохранить лексическую область в TypeScript с функцией обратного вызова
Это лучший способ добиться закрытия, которое Стив Фентон сделал в своем ответе. Я предпочитаю его, потому что использование документов подписи метода.
В принципе, используйте такой метод:
fadeOutLambda(outerThis: YourClass): {(d: number, i: number): number}{
return function(d: number, i: number){
// Put your "fadeOut" logic here
// refer to "this" to mean the dynamically scoped "this"
// refer to "outerThis" to refer to the class instance
alert(outerThis); // lexically scoped class instance
alert(this); // dynamically scoped context caller
return 999;
}
}
Ответ 3
Позвольте мне предоставить другое решение, не использующее лямбда.
Вы можете прикрепить это свойство как свойство (называемое мной в этом примере).
class MyClass
{
constructor()
{
var button: HTMLElement = document.getElementById("buttonID");
(button as any).me = this;
button.onclick = this.buttonClick;
}
private buttonClick(e): boolean
{
var me: MyClass = (this as any).me;
// Implementation using this (the button) and me (the class)
return false;
}
}