javascript 我如何 setInterval 来调用类中的函数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7942138/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 01:49:05  来源:igfitidea点击:

how do I setInterval to call a function within a class

javascriptscopesettimeout

提问by fenerlitk

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?

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

回答by nnnnnn

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

的值this取决于函数的调用方式。当您将函数作为构造函数调用时,使用newthenthis将引用正在创建的对象。同样,当您使用点符号调用函数时,run.start()thenthis将引用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();

Note also that you've created a function called runanda 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.

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

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

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

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 selfstuff 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.

但是我关于不给你的构造函数和后面的变量同名的观点仍然有效,我会把所有的self东西都留在里面,因为如果draw()确实需要访问this. 如果要向draw()函数添加参数,也需要这样做。

回答by Yas

The bind()method!

bind()的方法!

See the following example in ES6:

请参阅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>

回答by Marian Bazalik

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

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