在 Javascript 中扩展继承的原型方法

Extend inherited prototype method in Javascript

我有一些 类(构造函数)与 "parent-child":

相关
// Abstract root SuperClass

function SuperClass() {
    this.CLASS_ID = "SUPER-CLASS";
    throw new Error('Failed to instantiate abstract class' + this.CLASS_ID);
}

SuperClass.prototype.sayHello = function() {
    alert('Hello, world!');
};

// Absctract ClassA inherits from SuperClass
// inherit() and extend() are generic functions from the David Flanagan`s 
// brilliand book "Definitive Guide"

function ClassA() {
    this.CLASS_ID = "CLASS-A";
    throw new Error('Failed to instantiate abstract class' + this.CLASS_ID);
}

ClassA.prototype = inherit(SuperClass.prototype);

// Concrete ClassB inherits from ClassA

function ClassB(initData) {
    this.CLASS_ID = "CLASS-B";
}

ClassB.prototype = inherit(ClassA.prototype);

extend(ClassB.prototype, {
    constructor: ClassB,

    welcomeNewDay: function() {
        this.sayHello();
        this.doSomethingElse();
    },

    doSomethingElse: function(){
        alert('Jumping');
    }
});

var classB = new ClassB();
classB.welcomeNewDay();

如何在不重载抽象 ClassA 的情况下正确扩展方法 .sayHello()

我试过这样做:

extend(ClassA.prototype, {
    sayHello: function() {
        this.__proto__.sayHello();
        this.sing();
    },

    sing: function() {
        alert('Lalala');
    }
});

问题是 .sing() 被调用了 3 次而不是 1 次。

如果我尝试:

this.__proto__.sayHello.call(this);

抛出异常:

Uncaught RangeError: Maximum call stack size exceeded

尝试访问初始 class:

extend(ClassA.prototype, {
    sayHello: function() {
        SuperClass.prototype.sayHello.call(this);
        this.sing();
    },

    sing: function() {
        alert('Lalala');
    }
});

或者只存储当前的sayHello()方法:

var initialSayHello = ClassA.prototype.sayHello;
extend(ClassA.prototype, {
    sayHello: function() {
        initialSayHello.call(this);
        this.sing();
    },

    sing: function() {
        alert('Lalala');
    }
});

您需要参考原始sayHello()方法。


Uncaught RangeError: Maximum call stack size exceeded

它被抛出是因为你实际上有一个无限递归,在方法中调用方法本身。