我在使用setInterval和类方法时遇到很多麻烦

时间:2018-10-17 05:33:49

标签: javascript

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

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计时函数,那么一切都会正常进行精细?我真的很沮丧。

1 个答案:

答案 0 :(得分:3)

考虑以下两个片段:

animatedSnake.next()

并且:

let method = animatedSnake.next;
method();

在第一个代码段中,next被称为animatedSnake对象的成员,因此this方法上下文中的next是指animatedSnake对象

在第二个片段中,next方法是与对象分离的,因此,this不再引用animatedSnake实例,而{{1} }函数被调用。这就是将方法传递给另一个函数(例如method)的方式。您可以使用setInterval方法手动设置上下文:

Function.prototype.bind

或用另一个函数包装语句:

setInterval(animatedSnake.next.bind(animatedSnake), 100)