如何setInterval来调用类中的函数

fen*_*itk 5 javascript scope settimeout

我有一个类:

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

但是我似乎无法this.draw()在setInterval中引用/调用,它说this.draw()不是一个函数,如果我删除引号就说无用的setInterval调用,我做错了什么?

nnn*_*nnn 13

值的this设置取决于函数的调用方式.当您使用调用一个函数作为构造new,然后this将参照对象被创建.同样,当你调用一个函数点符号一样run.start(),然后this将引用run.但是当setInterval被调用的代码运行时this并不意味着你的想法.您可以做的是保存this对该引用的引用,然后使用该引用,如下所示:

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();
Run Code Online (Sandbox Code Playgroud)

另请注意,您已创建了一个名为的函数run 一个名为的变量run- 您需要为它们指定不同的名称.在我的代码中(记住JS区分大小写)我已经将函数名称更改为以大写"R"开头 - 这是要作为构造函数运行的函数的约定.

编辑:好的,看看其他答案,我可以看到,也许我过于复杂,只要draw()不需要访问this它就可以说:

this.interval = setInterval(this.draw, 1000);
Run Code Online (Sandbox Code Playgroud)

但是我没有给你的构造函数和后来变量同名的观点仍然存在,我将留下所有的self东西,因为它是一种技术,如果draw()需要访问你将需要this.如果要向draw()函数添加参数,则还需要这样做.

  • 如果`draw`在其中需要正确的`this`,当在`setInterval(this.draw,1000)`版本中调用`draw`时,`this`draw`将不起作用,`this`将是`window`里面'画'.如果`draw`使用实例属性(即它确实是一个方法而不仅仅是普通函数),那么所有`self`东西都是必要的. (2认同)

Yas*_*Yas 10

bind()的方法!

请参阅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>
Run Code Online (Sandbox Code Playgroud)