使用多级继承扩展基类方法(typescript)

Sta*_*e26 12 typescript

我有3个班:

class A{
    DoStuff(){
        return "Called from A";
    }
}

class B extends A {

    constructor(){
        super();
        var baseDoStuff = super.DoStuff;
        this.DoStuff = function(){
            return baseDoStuff() + " and Called from B";
        }
    }
}

class C extends B { 
    constructor(){
        super();
        var baseDoStufffff = super.DoStuff;
        this.DoStuff = function(){
            return baseDoStufffff() + " and Called from C";
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我期望C级的DoStuff()调用B的DoStuff()(它反过来会调用A的).

但是,在C上调用DoStuff()只返回"从A调用并从C调用".我在这做错了什么?这不应该叫B的方法吗?

这方面的一个工作示例可以在这里找到:

bas*_*rat 15

每当您需要使用superUse类方法而不是类成员时:

class A{
    DoStuff(){
        return "Called from A";
    }
}

class B extends A {

    constructor(){
        super();      

    }   
    DoStuff (){
        return super.DoStuff() + " and Called from B";
    }
}

class C extends B { 
    constructor(){
        super();                
    }

    DoStuff(){
            return super.DoStuff() + " and Called from C";
    }
}

var c = new C();
console.log(c.DoStuff());
Run Code Online (Sandbox Code Playgroud)

尝试一下(打印从A调用,从B调用,从C调用)

这是因为super转换为.prototypeie super.DoStuff()成为_super.prototype.DoStuff()并且唯一可用的东西.prototype是类方法.

更多:http://basarat.github.io/TypeScriptDeepDive/#/super


Jef*_*ski 7

JavaScript实际上没有方法.TypeScript尝试用熟悉的符号隐藏原型链的工作方式,但是像所有抽象一样,它不完美.原型链的要点是,当你调用c.DoStuff()它时,它会在c实例上查找DoStuff,而不是原型(C),然后是原型(B),然后是原型(A),然后是原型(Object).

这不仅适用于功能,也适用于您可能查找的任何成员.函数在JavaScript中并不是特别的,具有讽刺意味的是它们使它们变得强大.

在A类中使用TypeScript的语法,你在A的原型中放置了一个函数DoStuff.您调用DoStuff的每个A实例都会在实例中查找它(并且可能无法在那里找到它)查看原型并查看您定义的函数.到现在为止还挺好.

然后你定义了一个扩展A的类B,所以原型链是B-> A-> Object.在B的构造函数中,您可以在每个实例上为DoStuff分配一个函数的新副本.(这会占用更多的内存.)因此,当你构造一个新的B并在其上调用DoStuff时,那里有一个函数而没有检查原型.这样才行.

现在定义一个扩展B的类C,原型链是C-> B-> A-> Object.同样,C的每个实例都获得分配给DoStuff的函数的副本.但是在构造函数中我们没有从B的实例中获取DoStuff,我们从原型中抓取它,并且我们没有将该函数直接添加到原型中.如果没有在那里找到它,我们将原型链转到A.prototype并找到一个DoStuff成员从那里使用.这就是为什么C引用了A的DoStuff.

如果您执行以下操作,则可以使代码按预期工作:

class B extends A {
    constructor() {
        super();
    }
}
B.prototype.DoStuff = function () {
    return A.prototype.DoStuff() + " and Called from B";
}
Run Code Online (Sandbox Code Playgroud)

但那只是愚蠢的.