1

I have some classes (constructors) that are related as "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();

How can I correctly extend method .sayHello() of the abstract ClassA without overloading it?

I`ve tried to make it this way:

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

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

The problem is that .sing() is invoked 3 times instead of 1.

If I try:

this.__proto__.sayHello.call(this);

It throws an exception:

Uncaught RangeError: Maximum call stack size exceeded

3
  • sayHello() is not method of the abstract ClassA .It is inherited from its prototype Commented Apr 8, 2016 at 7:03
  • Sometime you use inherit and sometime use prototype.Why?Is there any requirements ? Commented Apr 8, 2016 at 7:07
  • @RIYAJKHAN I use inherit() when I need to get (copy) all possible methods from the ancestor class prototype. I used prototype (here I guess? SuperClass.prototype.sayHello") just to quick type new method. Commented Apr 8, 2016 at 7:24

1 Answer 1

1

Try to access the initial class:

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

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

or just store the current sayHello() method:

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

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

You need to have the reference to the original sayHello() method.


Uncaught RangeError: Maximum call stack size exceeded

It is thrown because you actually have an infinite recursion, calling the method itself in the method.

Sign up to request clarification or add additional context in comments.

2 Comments

Dmitri, thank you for yor help. I see you`ve suggested to hardcode the link to the ancestor prototype method and it works. Can I resolve the same problem without the explicit writing the class name in the first case?
@J.P.Remarg You need to access somehow the prototype, and using the Constructor is ok. But it would be something weird: this.__proto__.__proto__.sayHello.call(this).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.