how do I setInterval to call a function within a class

故事扮演 提交于 2019-12-12 07:18:51

问题


I have a class like:

function run(){
this.interval;
this.start = function(){
    this.interval = setInterval('this.draw()',1000);
};
this.draw = function(){
    //some code
};} var run = new run(); run.start();

however I can't seem to reference/call this.draw() within the setInterval, it says this.draw() is not a function, and if I remove the quotes it says useless setInterval call, what am I doing wrong?


回答1:


The value of this is set depending on how a function is called. When you call a function as a constructor using new then this will refer to the object being created. Similarly when you call a function with dot notation like run.start() then this will refer to run. But by the time the code run by the setInterval is called this doesn't mean what you think. What you can do is save a reference to this and then use that reference, like the following:

function Run(){
  var self = this;

  self.start = function(){
    self.interval = setInterval(function() { self.draw(); },1000);
  };

  self.draw = function(){
    //some code
  };
}

var run = new Run();

run.start();

Note also that you've created a function called run and a variable called run - you need to give them different names. In my code (bearing in mind that JS is case sensitive) I've changed the function name to start with a capital "R" - which is the convention for functions intended to be run as constructors.

EDIT: OK, looking at the other answers I can see that just maybe I overcomplicated it and as long as draw() doesn't need to access this it would've been fine to just say:

this.interval = setInterval(this.draw, 1000);

But my point about not giving your constructor and later variable the same name still stands, and I'll leave all the self stuff in because it is a technique that you will need if draw() does need to access this. You would also need to do it that way if you were to add parameters to the draw() function.




回答2:


The bind() method!

See the following example in ES6:

<!DOCTYPE html>
<html>

<body>
    <canvas id="canvas" width="200" height="200" style="border: 1px solid black"></canvas>

    <script>
        class Circles {
            constructor(canvas, r = 5, color = 'red') {
                this.ctx = canvas.getContext('2d')
                this.width = canvas.width
                this.height = canvas.height

                this.r = r
                this.color = color

                setInterval(
                    this.draw.bind(this),
                    1000
                )
            }

            draw() {
                this.ctx.fillStyle = this.color

                this.ctx.beginPath()
                this.ctx.arc(
                    Math.random() * this.width,
                    Math.random() * this.height,
                    this.r,
                    0,
                    2 * Math.PI
                )

                this.ctx.fill()
            }
        }
    </script>

    <script>
        var canvas = document.querySelector('#canvas')
        var circles = new Circles(canvas)
    </script>
</body>

</html>



回答3:


function run(){
    this.interval;
    this.start = function(){
        this.interval = setInterval(this.draw,1000);
    };
    this.draw = function(){
        //some code
    }
;} 

var run = new run();
run.start();


来源:https://stackoverflow.com/questions/7942138/how-do-i-setinterval-to-call-a-function-within-a-class

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!