Javascript TypeScript-如何继承类并重写lambda方法
我有一个继承的类,需要父类有一个虚拟方法,该方法在子类中被重写。这个方法是从基构造函数调用的,需要访问实例属性,所以它需要是一个lambda函数,所以“This”就是“This”。问题是,重写lambda方法对我来说不像重写非lambda方法那样有效。这可能吗?如果没有,我想了解原因 另外,当只从构造函数调用方法时,“this”是否始终与“\u this”相同Javascript TypeScript-如何继承类并重写lambda方法,javascript,inheritance,typescript,lambda,Javascript,Inheritance,Typescript,Lambda,我有一个继承的类,需要父类有一个虚拟方法,该方法在子类中被重写。这个方法是从基构造函数调用的,需要访问实例属性,所以它需要是一个lambda函数,所以“This”就是“This”。问题是,重写lambda方法对我来说不像重写非lambda方法那样有效。这可能吗?如果没有,我想了解原因 另外,当只从构造函数调用方法时,“this”是否始终与“\u this”相同 class Base { protected prop = null; constructor() {
class Base {
protected prop = null;
constructor() {
this.init();
this.initLambda();
}
init() {
console.log("Base init");
}
initLambda = () => {
console.log("Base initLambda");
}
}
class Derived extends Base {
constructor() {
super();
}
init() {
console.log("Derived init");
}
initLambda = () => {
//let x = this.prop;
console.log("Derived initLambda");
}
}
输出:派生初始化
Base initLambda问题在于lambda是一个属性 编译为javascript时,
Base
类变为
var Base = (function () {
function Base() {
this.prop = null;
this.initLambda = function () {
console.log("Base initLambda");
};
this.init();
this.initLambda();
}
Base.prototype.init = function () {
console.log("Base init");
};
return Base;
}());
如您所见,initLambda
是在Base
的构造函数中定义的,因此您无法覆盖它
调用super()
调用Base
构造函数,该构造函数使用Base
中的代码定义this.initLambda
,并运行它。这就是你的结果
查看好吧,你不能拥有它。
没有,但它被关闭为“设计” 您应该使用常规方法:
class Base {
protected prop = null;
constructor() {
this.init();
this.initLambda();
}
init() {
console.log("Base init");
}
initLambda() {
console.log("Base initLambda");
}
}
class Derived extends Base {
constructor() {
super();
}
init() {
console.log("Derived init");
}
initLambda() {
console.log("Derived initLambda");
}
}
然后它就会起作用
对于保留此的正确,您始终可以将对该方法的调用作为箭头函数传递:
doit() {
setTimeout(() => this.init(), 1);
}
setTimeout(this.init.bind(this));
或使用以下功能:
doit() {
setTimeout(() => this.init(), 1);
}
setTimeout(this.init.bind(this));
此外,typescript编译器生成的\u这个东西只是对ES5的arrow函数进行了修改,但是如果您将目标更改为ES6,它将不会使用它
编辑:
可以将绑定的方法另存为成员:
class Base {
...
public boundInit: () => void;
constructor() {
...
this.boundInit = this.initLambda.bind(this);
setTimeout(this.boundInit, 500);
}
...
因此,当我执行new-Derived()
时,我得到的是:
派生初始化
200毫秒后导出的initLambda//
为什么它需要是一个“lambda”?@NitzanTomer-当函数需要访问“\u this”时,我通常使用“实例箭头函数”,以确保我始终拥有正确的上下文。我不相信箭头函数会做你认为的事情。其中的this
将成为周围环境的this
。你说*这个方法是从基构造函数调用的,需要访问实例属性,所以它需要是一个lambda函数,所以“This”是“_This”*,但我认为你不理解如何派生类。构造函数中调用的方法将始终调用基类上的版本(如果存在),即使它是以正常方式定义的。我想您可以说您可以重写它,但在实例化之前它不会被重写。@user210757 yes。基本上,不要在基构造函数中调用this.initLambda()
,在Derived
中重写它,然后从Derived
中调用它。按照这些思路,我认为这可能在基构造函数中起作用,但没有-让x=()=>this.initLambda();x();您可以将这样的绑定函数保存为成员,然后使用它们。你认为“不工作”是什么意思?没有调用派生方法-这正是我试图做的。检查我的修订答案“有一个问题是打开的,但它被关闭为“按设计”-链接已断开