tnhu / jsface

Small, fast, elegant, powerful, and cross platform JavaScript OOP library. Support main(), singleton, super call, private, mixins, plugins, AOP and more.
MIT License
301 stars 46 forks source link

Maximum call stack size exceeded when C extends B and B extends A #17

Closed hehachris closed 9 years ago

hehachris commented 10 years ago
var Class = require('jsface').Class;

var A = Class(function() {
    return {
        constructor: function() {
            console.log('A');
        }
    };
});

var B = Class(A, function() {
    return {
        constructor: function() {
            this.$class.$super.call(this);

            console.log('B');
        }
    };
});

var C = Class(B, function() {
    return {
        constructor: function() {
            this.$class.$super.call(this);

            console.log('C');
        }
    };
});

new A; // OK
console.log();
new B; // OK
console.log();
new C; // throws RangeError: Maximum call stack size exceeded
tnhu commented 10 years ago

Hi Chris,

Thanks for reporting. Since v2.2.0, I introduced $class as a reference to class definition. Yeah, did not have enough unit tests to cover recursive case.

Working on it. In the meaning time, there's a workaround:

var A = Class(function() {
    return {
        constructor: function() {
            console.log('A');
        }
    };
});

var B = Class(A, function() {
    return {
        constructor: function() {
            A.call(this);
            console.log('B');
        }
    };
});

var C = Class(B, function() {
    return {
        constructor: function() {
            B.call(this);
            console.log('C');
        }
    };
});
xmojmr commented 10 years ago

I've hit same problem. Glad to know there is a clear way to get rid of the magic mandatory formula this.$class.$super.call... It is the only way mentioned in the documentation so I used it.

C++ did not have "__super" for quite long (see e.g. http://stackoverflow.com/questions/180601/using-super-in-c) and still many millions of lines of object oriented code was written in that language.

I guess in JavaScript the class hierarchy won't be so deep so that developer would not know or remember what is the base class name. As type-less language without validating compiler it would otherwise become quickly not-manageable.

For me the issue can be closed and formula this.$class.$super.call.. should be removed from the documentation for good