“错误”;这";从TypeScript子类中的回调调用超类方法时

“错误”;这";从TypeScript子类中的回调调用超类方法时,typescript,Typescript,我有一些类型脚本代码(实际上)如下所示: class User { name: string = "Bob"; sayHello(): void { console.log("Hello, " + this.name); } } class RegisteredUser extends User { name: string = "Frank"; sayHello(): void { var s = super;

我有一些类型脚本代码(实际上)如下所示:

class User {
    name: string = "Bob";
    sayHello(): void {
        console.log("Hello, " + this.name);
    }
}

class RegisteredUser extends User {
    name: string = "Frank";
    sayHello(): void {
        var s = super;
        setTimeout(() => s.sayHello(), 1000);
    }
}

var registeredUser = new RegisteredUser();
registeredUser.sayHello();
问题是TypeScript(莫名其妙的是,IMO)遵循了关于“this”的奇怪JavaScript规则,而不是像世界上其他编程语言那样。因此,当从RegisteredUser.sayHello()中的覆盖调用User.sayHello()时,
this
指向用户类而不是实例化的RegisteredUser对象,因此实际记录的是:

Hello, undefined
除了这样做对我来说没有任何意义之外(请参阅),解决这个问题的最佳方法是什么,以便User.sayHello()中的
this
在从回调调用时指向正确的对象?

好的,这样做:

setTimeout(() => s.sayHello.call(this), 1000);

如果您避开
var s=super
赋值,并直接调用
super.sayHello
,TS将为您插入魔法咒语。在TS操场上试试。

这同样有效,并且不再需要
s
var:

sayHello(): void {
    setTimeout(super.sayHello.bind(this), 1000);
}

我特别试过了,但它不让我这么做。编译器给了我一个错误,“关键字
super
只能在类实例方法中使用。”当然,我认为这是语言中的一个错误-TS需要看起来更像C#,IMO,而不像JS-但我不确定Anders Hejlsberg是否同意我的观点:-)。你说得很对,我错过了操场上的错误提示
.call
.bind
是ES5解决方案,但应该有更好的方法。听起来像是es讨论的主题(我关于它的电子邮件似乎卡在了某个过滤atm中)。关于es讨论的反馈,来自ES6规范编辑器:谢谢,@claus!值得一提的是,我真的认为与
这个
相关的问题是目前JS中最大的问题之一。似乎编码人员利用
这一定义行为的频率要比被迫绕过它的频率低得多。如果ES6能够解决这个问题,那将是非常棒的,至少在课堂上是如此。甚至可能是一个单独的关键字(
me
that
?),它在类内部总是绑定到类,而不管函数是否被分配到其他地方。typescript遵循javascript的规则,因为它是javascript。但它不是,至少在处理类时不是。在一个类中,应该有一个关键字-如果不是
this
那么
me
或者
that
或者其他什么-那就是绝对的,句号,绑定到该类。人们多久利用一次JS中的
实现这个
,而不是多久被迫去解决这个问题?当涉及松散函数时,我可以理解JS规则(
this
没有要绑定的类,因此如果你想要得到关键字,它必须绑定到函数的所有者)。但是当涉及到类时,规则需要有所不同。好吧,从从从javascript到typescript的移植角度来看。如果我现在使用一个大型纯javascript应用程序,并将其放入typescript中,我可以更改模块定义以使用class关键字,并且一切仍然可以工作。然后,我可以有条理地删除“that=this”hacks并用arrow syntax/lambdas替换它们,它将工作,并且转换过程是显式的。如果删除class关键字完全破坏了其他一切,那么这是一个调试过程,而不是严格的移植。我不知道。我在学术上同意你的观点,但我内心的实用主义者并不确定。@x0n-关于移植位的观点很好。您认为我的单独关键字(
me
?)的想法如何?它只在类内部可用,应该始终指向类实例,而不管您是否使用
函数()调用它
或lambdas或它在其他地方被分配的位置?但你不是真的调用了
this.sayHello
,因为上下文是
this
而不是
super
?@Cody否,它明确告诉
setTimeout
调用
super.sayHello
(基类版本)但要将当前
作为上下文传递。