javascript - 超出最大调用堆栈大小 - 没有明显的递归

标签 javascript class inheritance recursion callstack

我花了大约 12 个小时查看这段代码并摆弄它,试图找出哪里存在递归问题,因为我遇到了“超出最大调用堆栈大小”错误,但没有找到了。请比我聪明的人帮助我!

到目前为止,我发现当我制作对象 spot 一个 circle 对象时,问题就消失了,但是当我把它做成一个时,' pip',我得到这个堆栈溢出错误。我用该死的显微镜检查了 pip 类,但仍然不知道为什么会这样!

var canvas = document.getElementById('myCanvas');

//-------------------------------------------------------------------------------------
// Classes
//-------------------------------------------------------------------------------------
//=====================================================================================
//CLASS - point
function point(x,y){
    this.x = x;
    this.y = y;
}
//=====================================================================================
// CLASS - drawableItem
function drawableItem() {
    var size = 0;
    this.center = new point(0,0);
    this.lineWidth = 1;
    this.dependentDrawableItems = new Array();
}
//returns the size
drawableItem.prototype.getSize = function getSize(){
    return this.size;
}
// changes the size of this item and the relative size of all dependents
drawableItem.prototype.changeSize = function(newSize){
    var relativeItemSizes = new Array;
    relativeItemSizes.length = this.dependentDrawableItems.length;
    // get the relative size of all dependent items
    for (var i = 0; i < this.dependentDrawableItems.length; i++){
        relativeItemSizes[i] = this.dependentDrawableItems[i].getSize() / this.size;
    }
    // change the size
    this.size = newSize;
    // apply the ratio of change back to all dependent items
    for (var i = 0; i < relativeItemSizes.length; i++){
        this.dependentDrawableItems[i].changeSize(relativeItemSizes[i] * newSize);
    }
}
//moves all the vertices and every dependent to an absolute point based on center
drawableItem.prototype.moveTo = function(moveX,moveY){
    //record relative coordinates
    var relativeItems = new Array;
    relativeItems.length = this.dependentDrawableItems.length;
    for (var i = 0; i < relativeItems.length; i++){
        relativeItems[i] = new point;
        relativeItems[i].x = this.dependentDrawableItems[i].center.x - this.center.x;
        relativeItems[i].y = this.dependentDrawableItems[i].center.y - this.center.y;
    }
    //move the center
    this.center.x = moveX;
    this.center.y = moveY;
    //move all the items relative to the center
    for (var i = 0; i < relativeItems.length; i++){
        this.dependentDrawableItems[i].moveItemTo(this.center.x + relativeItems[i].x,
            this.center.y + relativeItems[i].y);
    }
}
// draws every object in dependentDrawableItems
drawableItem.prototype.draw = function(ctx){
    for (var i = 0; i < this.dependentDrawableItems.length; i++) {
        this.dependentDrawableItems[i].draw(ctx);
    }
}

//=====================================================================================
//CLASS - circle
function circle(isFilledCircle){
    drawableItem.call(this);
    this.isFilled = isFilledCircle
}
circle.prototype = new drawableItem();
circle.prototype.parent = drawableItem.prototype;
circle.prototype.constructor = circle;
circle.prototype.draw = function(ctx){
    ctx.moveTo(this.center.x,this.center.y);
    ctx.beginPath();
    ctx.arc(this.center.x, this.center.y, this.size, 0, 2*Math.PI);
    ctx.closePath();
    ctx.lineWidth = this.lineWidth;
    ctx.strokeStyle = this.outlineColor;
    if (this.isFilled === true){
        ctx.fill();
    }else {
        ctx.stroke();
    }
    this.parent.draw.call(this,ctx);
}

//=====================================================================================
//CLASS - pip
function pip(size){
    circle.call(this,true);
}
pip.prototype = new circle(false);
pip.prototype.parent = circle.prototype;
pip.prototype.constructor = pip;

//----------------------------------------------------------------------
// Objects/variables - top layer is last (except drawable area is first)
//----------------------------------------------------------------------
var drawableArea = new drawableItem();

var spot = new pip();
spot.changeSize(20);
drawableArea.dependentDrawableItems[drawableArea.dependentDrawableItems.length] = spot;

//------------------------------------------
// Draw loop
//------------------------------------------
function drawScreen() {
    var context = canvas.getContext('2d');
    context.canvas.width  = window.innerWidth;
    context.canvas.height = window.innerHeight;

    spot.moveTo(context.canvas.width/2, context.canvas.height/2);

    drawableArea.draw(context);
}

window.addEventListener('resize', drawScreen);

这是演示:http://jsfiddle.net/DSU8w/

最佳答案

this.parent.draw.call(this,ctx);

是你的问题。在 pip 对象上,父级将是 circle.prototype。所以当你现在调用 spot.draw() 时,它会调用 spot.parent.draw.call(spot),其中 this.parent仍然是 circle.prototype...

您需要从 circle.prototype.draw 显式调用 drawableItem.prototype.draw.call(this)。顺便说一句,你应该 not use new for the prototype chain .

关于javascript - 超出最大调用堆栈大小 - 没有明显的递归,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20463145/

相关文章:

javascript - 悬停时的 Z 索引

javascript - 有什么方法可以将参数传递给 $.change() 方法吗?

javascript - Elasticsearch 5.3 - 找不到geo_point字段

C++ 错误 C2228

java - 如何修改/覆盖从 Groovy 基本脚本继承的变量?

scala - 如何从Scala中的内部类引用外部对象

java - 使用泛型 <K> 减少重复代码?

javascript - 如何在滚动时将 jQuery 阴影函数应用于具有相同类名的多个元素

c++ - 虚表指针

c++类 friend