Javascript I';我在setInterval和class方法方面遇到了很多麻烦
我总是遇到奇怪的问题。在做了一些研究之后,我找不到关于它们的任何东西,所以我想我应该来这里展示它们。我有一个相当长的课程,但我将包括相关的部分:Javascript I';我在setInterval和class方法方面遇到了很多麻烦,javascript,Javascript,我总是遇到奇怪的问题。在做了一些研究之后,我找不到关于它们的任何东西,所以我想我应该来这里展示它们。我有一个相当长的课程,但我将包括相关的部分: class AnimatedSnake { constructor(canvasId, coordinates) { this.coordinates = coordinates; this.direction = 2; this.ctx = document.getElementById(canvasId).getCon
class AnimatedSnake {
constructor(canvasId, coordinates) {
this.coordinates = coordinates;
this.direction = 2;
this.ctx = document.getElementById(canvasId).getContext("2d");
// 0 - .99, describes how far along snake is between coordinates
this.progress = 0;
}
erase() {
for (let i = 0; i < this.coordinates.length; i++) {
let c1 = this.coordinates[i][0],
c2 = this.coordinates[i][1];
this.ctx.clearRect(c1 * 31, c2 * 31, 31, 31);
}
}
next() {
this.progress += 0.01;
if (this.progress >= 1) {
this.progress %= 1;
let nextCoord = this.coordinates[4].slice();
nextCoord[0] += ((this.direction % 2) * this.direction);
nextCoord[1] += ((!(this.direction % 2) * (this.direction / 2)));
this.coordinates.push(nextCoord);
this.coordinates.shift();
}
console.log(this.erase);
this.erase();
this.draw();
}
}
class AnimatedSnake{
构造函数(canvasId,坐标){
这个。坐标=坐标;
这个方向=2;
this.ctx=document.getElementById(canvasId.getContext(“2d”);
//0-.99,描述了蛇在坐标之间的距离
这个进度=0;
}
抹去{
for(设i=0;i=1){
这1.3%=1;
设nextcord=this.coordinates[4].slice();
下一个命令[0]+=((this.direction%2)*this.direction);
下一个命令[1]+=((!(this.direction%2)*(this.direction/2));
这个.coordinates.push(下一个命令);
this.coordinates.shift();
}
console.log(this.erase);
这个;
这个.draw();
}
}
到目前为止,如果我手动(即从控制台)调用
AnimatedSnake.next()
,我可以无限期地调用它。但是,当我将函数置于间隔或超时状态时-setInterval(AnimatedSnake.next,100)
,在第一次运行时,它突然声称AnimatedSnake.erase不是一个函数。我尝试将AnimatedSnake.erase()
直接放在间隔中,当我这样做时,出于某种荒谬的原因,它会告诉我它不能接受AnimatedSnake.coordinates
的长度属性,它声称该属性未定义。在我的代码中,没有任何地方可以重新定义这些东西<代码>坐标
已更改,但不应在任何点取消定义。当然,erase
是一种我永远不会改变的方法。有人知道为什么用setInterval
或setTimeout
调用这些函数时会发生奇怪的事情,但是如果我在没有JavaScript计时函数的情况下重复调用这些函数(即使是在for循环中),一切都会正常进行吗?我真的被难住了。想想这两个片段:
animatedSnake.next()
以及:
在第一个片段中,next
被称为animatedSnake
对象的一个成员,因此在next
的上下文中,此方法引用animatedSnake
对象
在第二个代码段中,next
方法与对象分离,因此调用方法
函数时,此
不再引用animatedSnake
实例。这就是如何将一个方法传递给另一个函数,如setInterval
。您可以使用Function.prototype.bind
方法手动设置上下文:
setInterval(animatedSnake.next.bind(animatedSnake), 100)
或使用另一个函数包装语句:
setInterval(() => animatedSnake.next(), 100)
当您将函数传递给setIntverval
时,您会失去绑定此
的上下文,因为它只传递函数引用。您可以尝试setInterval(()=>AnimatedSnake.next,100)
或setInterval(AnimatedSnake.next.bind(AnimatedSnake),100)
为函数调用保留正确的上下文。AnimatedSnake的实例在哪里?它们不是用作动画snake的静态方法。接下来@sajalpreetsin我有一个实例,我只是觉得我不需要显式地显示一个来描述我的问题。不用担心:)我将把它包装在另一个函数中-我可能在调试时就应该想到这一点,但我仍然很高兴我问了这个问题,因为我没有意识到回调将方法与对象/类分离。谢谢你的解释@ElleNolan不客气!由于主题是this
关键字,我想您可能会发现这个问题的答案很有用:
setInterval(() => animatedSnake.next(), 100)