【问题标题】:How to start a counter for a setInterval如何为 setInterval 启动计数器
【发布时间】:2014-05-13 19:56:13
【问题描述】:

我有这段代码可以工作,但我想改进它:

var c = canvas.getContext("2d"); 
//this is called as an object method I created
var animar = function () {
   var obj = this;//saves the object that called it to later access to its properties
   var counter= 0;
   var animacion = setInterval(function(){
            c.save()
            c.clearRect(0, 0, canvas.width, canvas.height);
            c.rotate(0.1*counter);
            obj.pintar();
            c.restore();
            counter++;

   }, 50);
}

我想使用一个外部函数以备将来使用,但是当我更改我拥有的代码时,出现了一个提升问题,我不知道如何在不覆盖它的情况下获取 rotar() 函数内部的计数器一直:

var animar = function () {
    var obj = this;
    var counter= 0;
    var animacion = setInterval(function(){
        rotar(obj)
    }, 50);
}

function rotar (obj) {
    c.save()
    c.clearRect(0, 0, canvas.width, canvas.height);
    c.rotate(0.1*counter);
    obj.pintar();
    c.restore();
    counter++;
}

我知道第一个有效,因为它们是嵌套的,而在第二个示例中则不是。如何在不使用全局变量的情况下为 setInterval 设置计数器? (我的意思是......如果我第二次调用它,它不会从 0 开始。如果我在 animar() 函数中将它设置为 0,它会起作用,但是我需要将它设置为 0在每个使用计数器或使用不同名称的计数器的函数中。这两种可能性听起来不太好。) 谢谢

【问题讨论】:

    标签: javascript setinterval hoisting


    【解决方案1】:

    您只需将var counter = 0 放在函数之外:

    var counter;
    var animar = function () {
        var obj = this;
        counter = 0; // reset every time before 'animacion'...
        var animacion = setInterval(function(){
            rotar(obj)
        }, 50);
    }
    function rotar (obj) {
        c.save()
        c.clearRect(0, 0, canvas.width, canvas.height);
        c.rotate(0.1*contador);
        obj.pintar();
        c.restore();
        counter++;
    }
    

    或者,如果您不想要全局变量,您可以按照 Walter 的回答,或者这样做:

    var animar = function () {
        var obj = this;
        var counter = 0; // new variable every time animar() is called
        var animacion = setInterval(function(){
            rotar(obj, counter);
            counter++;
        }, 50);
    }
    function rotar (obj, counter) {
        c.save()
        c.clearRect(0, 0, canvas.width, canvas.height);
        c.rotate(0.1*contador);
        obj.pintar();
        c.restore();
    }
    

    【讨论】:

    • 是的,但我在问题的末尾指定它应该不使用全局计数器。
    • 我的意思是......如果我第二次调用它,它不会从 0 开始。如果我在 animar() 函数中将它设置为 0,它会起作用,但是我' d 需要在每个使用计数器或使用具有不同名称的计数器的函数中将其设置为 0。这两个可能性听起来不太好。
    • 已更新为重置为 0...如果您仍然不希望计数器在外面(为什么?),我可以再次更新...但是您能先告诉我为什么吗?
    • 我对此了解的不够多,不能说这是否通常是这样完成的,每次函数需要计数器时都会重置一个全局计数器,但这对我来说似乎并不优雅.稍后很容易忘记重新设置它。但也许没有更好的方法,这就是为什么我要问是否有。
    • 我更新添加了一种无需全局变量的方法,或者您可以按照 Walter 的方式进行操作。所有这些都是有效的 IMO,选择取决于上下文等。
    【解决方案2】:

    counter 限定在animar 对象内:

    var animar = function () {
        var obj = this;
        obj.counter= 0;
        var animacion = setInterval(function(){
            rotar(obj)
        }, 50);
    }
    
    function rotar (obj) {
        c.save()
        c.clearRect(0, 0, canvas.width, canvas.height);
        c.rotate(0.1*obj.counter);
        obj.pintar();
        c.restore();
        obj.counter++;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-12-11
      • 1970-01-01
      • 2011-12-28
      • 1970-01-01
      • 2012-01-22
      • 2021-09-28
      • 2021-03-17
      相关资源
      最近更新 更多