我希望我能得到一些帮助,弄清楚为什么我的代码会导致堆栈溢出。
有关守则:
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构造函数中调用RegularObjects时,它会再次尝试调用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];
}
}
};发布于 2012-09-18 03:10:21
问题
在RegularObject的构造函数中,您将其BaseClass方法的上下文设置为RegularObject。现在,当您输入SuperObject的构造函数时,"this“将引用RegularObject(您刚刚来自的同一个对象),然后再次调用RegularObject的BaseClass方法(使其与RegularObject的构造函数中的this.BaseClass.call(this);相同)。因为您再次使用同一个对象“调用”BaseClass,所以您将得到一个堆栈溢出/无限循环。
不是最好的解释,但也许一些例子会有帮助.
示例
下面是一个简单的代码块,突出显示正在发生的事情
小提琴:http://jsfiddle.net/GVkDv/1/
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(); 解决方案
要修复它,您需要维护一个上下文对象来引用继承基类的实例。
示例:
小提琴:http://jsfiddle.net/bboone/GVkDv/6/
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. 我应该指出,有很多详细的文档/审核过的继承模式。
下面是一些例子:
https://stackoverflow.com/questions/12468659
复制相似问题