这又迷路了

时间:2014-07-14 21:46:18

标签: javascript this

我以为我修好了但看起来没有。什么发生了什么:

canvas.mousemove事件由viewport.onMouseMove.bind(viewport)函数处理(视口是类的实例)。

onMouseMove函数的末尾,它调用this.Draw()(指viewport.Draw()函数)。

viewport.Draw()循环遍历所有项目并在每个项目上调用Items[i].Draw(ctx),其中ctx是后缓冲区画布上下文。

现在,如果正在绘制的项目继续并使用ctx在那里绘制一些东西然后(在其Draw函数中),使用它来引用它自己,一切正常。例如

this.Draw = function(ctx) {
    ctx.beginPath();
    ctx.moveTo(this.x1, this.y1);
    ctx.lineTo(this.x2, this.y2);
    ctx.lineWidth = 1;
    ctx.strokeStyle = "#000000";
    ctx.stroke();
};

但是,如果对象是一个容器,其中包含项目并尝试循环并像这样绘制它们

this.Draw = function(ctx) {
    for (j = 0; j < this.Items.length; j++) {
        this.Items[j].Draw(ctx);
    }
};

当它进入Items[j].Draw时,&#34;这个&#34;失去一切意义。 alert(this)生成&#34;对象对象&#34;我无法弄清楚它所指的是什么(它不是视口,也不是容器,也不是它需要的物品)。另外一个奇怪的事情 - 我不得不改变容器对象循环以使用j而不是i,否则它会创建一个永久循环(就像viewport.draw的i'一样和item[i].draw是一样的。)

2 个答案:

答案 0 :(得分:1)

你的问题有点不清楚。 this.Items是一个与this原型相同的对象数组吗?即。拼图?此外,是否要共享j计数器

无论如何,功能背景&#39;使用this.apply函数,.call值可以很容易地更改为您需要的值:

this.Draw = function(ctx) {
    for (var j = 0; j < this.Items.length; j++) {
        // These two are the same as what you have in the question
        this.Draw.call(this.Items[j], ctx);
        this.Draw.apply(this.Items[j], [ctx]);
        // This is what you had in the question if Draw is different for Items:
        this.Items[j].Draw(ctx);
        this.Items[j].Draw.call(this.Items[j], ctx);
        // Will preserve the this reference within the nested call
        this.Items[j].Draw.call(this, ctx);
    }
};

答案 1 :(得分:0)

不确定问题是什么,但我的评论建议this是调用对象:

//this in someFunction is window
setTimeout(myObject.someFunction, 200);
//this in someFunction is button
button.onClick=myObject.someFunction;

不确定在调用它时你想要this是什么,但是如果它必须是Items [j]那么你的代码就可以了,也许其他东西会导致你的问题。我建议使用firebug在Chrome或Firefox中使用console.log对象,使用F12打开控制台并检查记录的对象。

以下是可以是Square或Circle的项目的示例代码;

var Shape = function Shape(args){
  //args.x1 or y1 can be 0, defaults to 2
  this.x1 = (args.x1 === undefined)? 2:args.x1;
  this.y1 = (args.y1 === undefined)? 2:args.y1;
  this.name = args.name||"unnamed";
}
//in this example Square and Cirle draw does the same
// so they can inherit it from Shape
Shape.prototype.draw=function(){
  console.log("this x1:",this.x1,"this y1:",this.y1,"name",this.name);
  //you can log complex values as well and click on them in the console
  // to inspect the details of the complex values (objects)
  // the above can be done in the following log
  console.log("in draw, this is:",this);
}
var Square = function Square(args){
  //re use parent constructor (parent is Shape)
  Shape.call(this,args);
}
//set prototype part of inheritance and repair constructor
Square.prototype=Object.create(Shape.prototype);
Square.prototype.constructor=Square;

var Circle = function Circle(args){
  //re use parent constructor (parent is Shape)
  Shape.call(this,args);
}
//set prototype part of inheritance
Circle.prototype=Object.create(Shape.prototype);
Circle.prototype.constructor=Circle;
//there is only one app so will define it as object literal
var app = {
  items:[],
  init:function(){
    var i = -1;
    while(++i<10){
      this.items.push(new Circle({x1:i,y1:i,name:"circle"+i}));
    }
    while(++i<20){
      this.items.push(new Square({x1:i,y1:i,name:"square"+i}));
    }
  },
  draw:function(){
    var i = -1;len=this.items.length;
    while(++i<len){
      this.items[i].draw();
    }
  }
}
app.init();
app.draw();//causes console.logs