我一直遇到奇怪的问题。经过研究后,我一直找不到他们的任何东西,所以我想来这里介绍他们。我有一个很长的课,但是我将包括相关的内容:
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();
}
}
到目前为止,如果我手动进行操作(即从控制台),可以无限期地调用
AnimatedSnake.next()
。但是,当我将函数放在一个间隔或超时中时-setInterval(AnimatedSnake.next, 100)
-突然,在第一次运行时就声称AnimatedSnake.erase is not a function
。我尝试将AnimatedSnake.erase()
直接放在间隔中,当我这样做时,出于某种荒谬的原因,它去了,并告诉我它不能采用AnimatedSnake.coordinates
的length属性,该属性声称是不确定的。在我的代码中没有任何地方可以重新定义这些内容。 coordinates
已更改,但在任何时候都不应未定义。而erase
当然是我永远不会改变的方法。有谁知道为什么用setInterval
或setTimeout
调用它们时会发生奇怪的事情,但是如果我重复调用这些函数(即使在for循环中)却没有JavaScript计时函数,那么一切正常吗?我真的很沮丧。 最佳答案
考虑以下两个片段:
animatedSnake.next()
和:
let method = animatedSnake.next;
method();
在第一个片段中,
next
被称为animatedSnake
对象的成员,因此this
方法上下文中的next
指的是animatedSnake
对象。在第二个片段中,
next
方法与对象分离,因此,当调用this
函数时,animatedSnake
不再引用method
实例。这就是将方法传递给另一个功能(例如setInterval
)的方式。您可以使用Function.prototype.bind
方法手动设置上下文:setInterval(animatedSnake.next.bind(animatedSnake), 100)
或将语句包装到另一个函数中:
setInterval(() => animatedSnake.next(), 100)
关于javascript - 我在使用setInterval和类方法时遇到很多麻烦,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52847856/