使用多层继承扩展基类方法(TypeScript)

19

我有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";
        }
    }
}

我本来期望类C的DoStuff()会调用B的DoStuff()(而B的DoStuff()会调用A的),

然而,只调用C上的DoStuff()却仅返回"Called from A and Called from C"。我在这里做错了什么?难道不应该也调用B的方法吗?

您可以在此处找到一个可工作的示例:

示例

2个回答

25

每当您需要使用super时,请使用类的方法而不是类的成员

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());

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


8

JavaScript并没有真正的方法。TypeScript试图用熟悉的符号来隐藏原型链的工作原理,但像所有的抽象一样,它是不完美的。原型链的要点是,当你调用c.DoStuff()时,它会在c实例、原型(C)、它的原型(B)、它的原型(A)和它的原型(Object)上查找DoStuff。

这不仅适用于函数,还适用于您可能查找的任何成员。在JavaScript中,函数并不是非常特殊,具有讽刺意味的是,这正是使它们强大的原因。

在您的A类中使用TypeScript的语法,将一个DoStuff函数放入A的原型中。您在每个A实例上调用DoStuff时,都会在实例中查找它(很可能在那里找不到),然后查看您定义的函数。到目前为止都很好。

然后,您定义了一个扩展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";
}

但那只是在胡闹。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接