Javascript 这又迷路了

Javascript 这又迷路了,javascript,this,Javascript,This,我以为我修好了,但看起来没有。发生的事情如下: canvas.mousemove事件由viewport.onMouseMove.bind(viewport)函数(viewport是类的实例)处理 在onMouseMove函数的末尾,它调用this.Draw()(参考viewport.Draw()函数) viewport.Draw()循环遍历所有项并调用items[i]。在每个项上绘制(ctx),其中ctx是后台缓冲区画布上下文 现在,如果正在绘制的项目继续进行,并使用ctx在那里绘制一些东西,然

我以为我修好了,但看起来没有。发生的事情如下:

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

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

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

现在,如果正在绘制的项目继续进行,并使用ctx在那里绘制一些东西,然后(在其绘制功能中),使用它来引用自身,那么一切都正常。比如说

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);
    }
};
this.Draw=函数(ctx){
对于(j=0;j

当它进入
项[j].Draw
时,“this”失去了所有意义<代码>警报(此)
生成“对象对象”,我不知道它指的是什么(它不是视口、容器或它需要的项目)。还有一件奇怪的事情——我不得不将容器对象循环改为使用
j
而不是
I
,因为否则它会创建一个永久循环(就像
视口的I。draw
项[I]。draw
是一样的)。

你的问题有些不清楚。
this.Items
是与
this
具有相同原型的对象数组吗?也就是说,嵌套?另外,
j
计数器是否打算共享

无论如何,函数上下文“
值可以很容易地更改为使用
时需要的任何值。应用
。调用
函数:

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);
    }
};
this.Draw=函数(ctx){
对于(var j=0;j
不确定问题出在哪里,但正如我的评论所示,
这是调用对象:

//this in someFunction is window
setTimeout(myObject.someFunction, 200);
//this in someFunction is button
button.onClick=myObject.someFunction;
不确定调用此
时希望它是什么,但如果必须是Items[j],则您的代码很好,可能是其他原因导致您出现问题。我建议在带有firebug的Chrome或Firefox中使用console.log对象,使用F12打开控制台并检查记录的对象

下面是项目的示例代码,可以是正方形或圆形

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
var Shape=函数形状(args){
//args.x1或y1可以为0,默认为2
this.x1=(args.x1==未定义)?2:args.x1;
this.y1=(args.y1==未定义)?2:args.y1;
this.name=args.name | |“未命名”;
}
//在本例中,方形和圆形绘制的效果相同
//所以他们可以从形状继承它
Shape.prototype.draw=function(){
log(“this-x1:”,this.x1,“this-y1:”,this.y1,“name”,this.name);
//您还可以记录复杂的值,并在控制台中单击它们
//检查复杂值(对象)的详细信息的步骤
//可以在以下日志中完成上述操作
log(“在绘图中,这是:”,这是);
}
变量平方=函数平方(args){
//重复使用父构造函数(父构造函数是形状)
Shape.call(这个,args);
}
//设置继承和修复构造函数的原型部分
Square.prototype=Object.create(Shape.prototype);
Square.prototype.constructor=Square;
变量圆=函数圆(args){
//重复使用父构造函数(父构造函数是形状)
Shape.call(这个,args);
}
//将原型设置为继承的一部分
Circle.prototype=Object.create(Shape.prototype);
Circle.prototype.constructor=Circle;
//只有一个应用程序,因此将其定义为对象文字
变量应用={
项目:[],
init:function(){
var i=-1;

虽然(++i
alert
是一个糟糕的调试工具。不要使用它。使用
console.log(this)
,然后检查浏览器的控制台(通常是Ctrl+Shift+J)。在这种情况下,结果是一样的。它是一个具有.Draw函数的各种对象实例数组。如果您使用console.log
this
(不在IE中)的值您可以看到值不是您的对象。这是因为
this
的值是调用对象。它是在您调用/调用函数时确定的,而不是在您声明函数时确定的。您拥有这个.Draw=函数的事实表明您不知道原型以及如何将函数大写。构造函数是在t可调用函数不应该。更多关于原型和<代码>此的值,这里:原型可以是相同的,但在我的测试用例中不是。Items数组中的对象有各种原型,唯一真正常见的是.Draw函数。不,我不打算被共享。在这种情况下,使用i引用<代码>此n this.Items[j].Draw的主体将引用
Items[j]
对象。这不是您想要的吗?(对于
j
,只需像上面那样放置
var
声明)