Javascript堆栈溢出错误

Javascript堆栈溢出错误,javascript,class,stack-overflow,Javascript,Class,Stack Overflow,我希望我能得到一些帮助,弄清楚为什么我的一段代码会导致堆栈溢出 有关守则: var ClassCreator = { create: function(class_object,ParentClass){ var created_class = null; created_class = function(){ if(arguments.length == 0){ this.con

我希望我能得到一些帮助,弄清楚为什么我的一段代码会导致堆栈溢出

有关守则:

var ClassCreator = {
    create: function(class_object,ParentClass){
        var created_class = null;


        created_class = function(){        
            if(arguments.length == 0){
                this.constructor();
            }else{
                this.constructor.apply(this,arguments);
            }        
        };

        this._grantInheritance(created_class,ParentClass);
        this._grantMethods(created_class,class_object);    

        return created_class;
    },

    _grantInheritance: function(created_class,ParentClass){
        if(ParentClass){
            created_class.prototype = ParentClass.prototype;
            created_class.prototype.BaseClass = ParentClass;
        }
    },

    _grantMethods: function(created_class,creation_object){
        //If there's no constructor provided, add a default constructor.
        if(!creation_object.constructor){
            creation_object.prototype.constructor = function(){};
        }

        //Add the creation_object's methods to the class we're creating.
        for(var property in creation_object){
            created_class.prototype[property] = creation_object[property];
        }
    }
};

var SuperSuperObject = ClassCreator.create({
    constructor: function(){
        document.write("Hello");
    }
});

var SuperObject = ClassCreator.create({
    constructor: function(){
        this.BaseClass.call(this);

        document.write(" ");
    }
},SuperSuperObject);

var RegularObject = ClassCreator.create({
    constructor: function(){
        this.BaseClass.call(this);

        document.write(" World");
    }
},SuperObject);

var test = new RegularObject();​
据我所知,当我在RegularObjects构造函数中调用this.BaseClass.call时,它试图再次调用RegularObjects构造函数,从而导致堆栈溢出。为什么它调用RegularObject的构造函数而不是SuperObject的构造函数,我不知道。有什么想法吗


编辑: 我的解决方案,以防将来有人喜欢:

var ClassCreator = {
    __PROTOTYPE_CONSTRUCTOR_SIGNAL__:  "1821fe18a870e71b29a6219e076b80bb",

    create: function(class_object,ParentClass){
        var created_class = null;


        created_class = function(){
            var call_class = null;


            if(arguments.length == 1){
                if(arguments[0] == ClassCreator.__PROTOTYPE_CONSTRUCTOR_SIGNAL__){
                    if(this.prototypeConstructor){
                        this.prototypeConstructor();
                    }

                    return;
                }
            }


            if(!this.__construct_stack){
                this.__construct_stack = 0;
            }
            call_class = this;
            for(var counter = 0;counter<this.__construct_stack;counter++){
                call_class = call_class.BaseClass.prototype;
            }
            this.__construct_stack++;


            if(arguments.length == 0){
                call_class.constructor.call(this);
            }else{
                call_class.constructor.apply(this,arguments);
            }


            return this;
        };


        this._grantInheritance(created_class,ParentClass);
        this._grantMethods(created_class,class_object); 

        return created_class;
    },

    _grantInheritance: function(created_class,ParentClass){
        if(ParentClass){
            created_class.prototype = new ParentClass(this.__PROTOTYPE_CONSTRUCTOR_SIGNAL__);
            created_class.prototype.BaseClass = ParentClass;
        }
    },

    _grantMethods: function(created_class,creation_object){
        //If there's no constructor provided, add a default constructor.
        if(!creation_object.constructor){
            creation_object.prototype.constructor = function(){};
        }

        //Add the creation_object's methods to the class we're creating.
        for(var property in creation_object){
            created_class.prototype[property] = creation_object[property];
        }
    }
};
var ClassCreator={
__原型(构造师)(信号)(1821fe18a870e71b29a6219e076b80bb),,
创建:函数(类\对象,父类){
创建的var_class=null;
已创建\u类=函数(){
var call_class=null;
if(arguments.length==1){
if(参数[0]==ClassCreator.\uu原型\u构造函数\u信号\uuuuu){
if(这个.prototypeConstructor){
这个.prototypeConstructor();
}
返回;
}
}
如果(!this.\u构造\u堆栈){
这个.\uu构造\u堆栈=0;
}
调用_class=this;
对于(var计数器=0;反问题
在RegularObject的构造函数中,您正在将其基类方法的上下文设置为RegularObject。现在,当您进入SuperObject的构造函数时,“”将引用RegularObject(与您刚才来自的对象相同),反过来,您将再次调用RegularObject的基类方法(使其与RegularObject的构造函数中的
this.BaseClass.call(this);
相同)。并且由于再次使用相同的对象“调用”基类,因此会得到stackoverflow/infinite循环

这不是最好的解释,但也许一些例子会有帮助

示例

下面是一个简化的代码块,它突出显示了正在发生的事情

小提琴:

解决方案 要修复它,您需要维护一个上下文对象来引用继承基类的实例

示例:

小提琴:

我应该指出,有很多经过良好记录/审查的继承模式

一些例子:

  • 约翰·雷斯格-
  • 道格拉斯·克罗克福德-
问题 在RegularObject的构造函数中,您正在将其基类方法的上下文设置为RegularObject。现在,当您进入SuperObject的构造函数时,“”将引用RegularObject(与您刚才来自的对象相同),反过来,您将再次调用RegularObject的基类方法(使其与RegularObject的构造函数中的
this.BaseClass.call(this);
相同)。并且由于再次使用相同的对象“调用”基类,因此会得到stackoverflow/infinite循环

这不是最好的解释,但也许一些例子会有帮助

示例

下面是一个简化的代码块,它突出显示了正在发生的事情

小提琴:

解决方案 要修复它,您需要维护一个上下文对象来引用继承基类的实例

示例:

小提琴:

我应该指出,有很多经过良好记录/审查的继承模式

一些例子:

  • 约翰·雷斯格-
  • 道格拉斯·克罗克福德-

我在这里没有看到任何设置“BaseClass”属性的内容。它是
ClassCreator.\u grantInheritance()
设置
创建的\u class.prototype.BaseClass
。您需要在浏览器中打开一个javascript控制台并逐步浏览代码。从那里很容易找到。
this.constructor()
调用
RegularObject.constructor
调用
this.constructor();
等。这就是我所做的。它让我知道,出于某种原因,它正在调用regular对象上的构造函数。这一切都很好。我想知道这(2)是怎么回事不过我没有看到任何设置“BaseClass”属性的内容。它是
ClassCreator.\u grantInheritance()
设置
创建的\u class.prototype.BaseClass
。您需要在浏览器中打开一个javascript控制台并逐步浏览代码。从那里很容易找到。
this.constructor()
调用
RegularObject.constructor
调用
this.constructor();
等。这就是我所做的。它让我知道,出于某种原因,它正在调用regular对象上的构造函数。这一切都很好。我想知道这(2)是怎么回事但是否决票。:/哈哈。这完全正确。我一秒钟前才意识到。编辑:我已经添加了我的解决方案,如果你想看的话。哈哈。这完全正确。我一秒钟前才意识到。编辑:我已经添加了我的解决方案,如果你想看的话。
var base = function(){
    //"this" now references the object we just came from along with it's methods 
    //and properties. 
    this.BaseClass.call(this); 
}

base.prototype.BaseClass = function(){ alert('made it to the base'); }

var derived = function(){
    alert('About to stackoverflow'); 
    this.BaseClass.call(this);//"call" keeps the context to the object we're on 
}

derived.prototype = new base(); //construct base the first time. 1st Alert.
derived.prototype.BaseClass = base; 

var x = new derived(); ​
var superbase = function(){
    var ctx = this; //maintain context of the initialized prototype object

    this.init = function(){
        alert('superbase'); 
    };

    this.init(); 
}

var base = function(){
    var ctx = this; //maintain context of the initialized prototype object

    this.init = function(){
        //ctx and this are referencing different objects
        ctx.BaseClass.init.call(this); 
    };

    this.init(); 
}

base.prototype = new superbase(); //construct superbase the first time. 1st Alert.
base.prototype.BaseClass = base.prototype;    

var derived = function(){
    var ctx = this; 

    this.init = function(){
        //ctx and this are referencing different objects
        ctx.BaseClass.init.call(this); 
    };

    this.init(); 
}

derived.prototype = new base(); 
derived.prototype.BaseClass = derived.prototype; 

var x = new derived(); 
x.init(); //call all the way down the inheritance chain.