Как я могу установитьInterval для вызова функции в классе - PullRequest
5 голосов
/ 30 октября 2011

У меня есть класс, как:

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

однако я не могу ссылаться / вызывать this.draw() в setInterval, он говорит, что this.draw() не является функцией, и если я удаляю кавычки, он говорит бесполезный вызов setInterval, что я делаю неправильно? *

Ответы [ 3 ]

12 голосов
/ 30 октября 2011

Значение 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 и переменную с именем run - вам нужно дать им разные имена. В моем коде (учитывая, что JS чувствителен к регистру) я изменил имя функции, чтобы оно начиналось с заглавной буквы «R» - это соглашение для функций, предназначенных для запуска в качестве конструкторов.

РЕДАКТИРОВАТЬ: ОК, глядя на другие ответы, я вижу, что просто возможно Я слишком усложнил это и , пока draw() не требуется доступ к this это было бы хорошо просто сказать:

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

Но моя точка зрения о том, чтобы не давать вашему конструктору и более поздней переменной одно и то же имя, остается в силе, и я оставлю все self в нем, потому что это метод, который вам понадобится, если draw() нужен доступ this. Вам также нужно будет сделать это таким образом, если вы добавите параметры в функцию draw().

10 голосов
/ 25 марта 2017

Метод 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>
0 голосов
/ 30 октября 2011
function run(){
    this.interval;
    this.start = function(){
        this.interval = setInterval(this.draw,1000);
    };
    this.draw = function(){
        //some code
    }
;} 

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