我一直遇到奇怪的问题。经过研究后,我一直找不到他们的任何东西,所以我想来这里介绍他们。我有一个很长的课,但是我将包括相关的内容:

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当然是我永远不会改变的方法。有谁知道为什么用setIntervalsetTimeout调用它们时会发生奇怪的事情,但是如果我重复调用这些函数(即使在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/

10-11 08:25