【问题标题】:JavaScript Recursion with Timing Event (setTimeout)带有计时事件的 JavaScript 递归 (setTimeout)
【发布时间】:2012-01-31 15:41:28
【问题描述】:

我正在尝试使用 JavaScript 构建一个计时器。这是我的功能:

var t;
function time(num){
    var buf = num;
    document.getElementById("test").innerHTML=buf;
    buf++;
    alert(buf + " " + num); //For troubleshooting
    t=setTimeout("time(buf)",1000);
}

如果我运行 time(0),ID="test" 的部分不会发生任何事情。每次调用函数时,num 始终等于 0,buf 始终等于 1(来自警报函数)。

我对 Java 和 C 很熟悉,而且我知道这适用于这些语言。我知道 JavaScript 也是一种按值传递的语言,那么为什么这个计时器不起作用呢?

另外,为什么我尝试(并将所有buf更改为num)时没有任何反应

t=setTimeout("time(num)",1000);

我知道还有其他方法可以创建计时器,但我想知道为什么这种方法不起作用。谢谢。

【问题讨论】:

  • 你可能认为这是递归,但实际上不是。 time() 被调用,然后它调用setTimeout() 并传递一个稍后将执行的字符串。然后,time() 返回,一段时间后,定时器代码再次调用time()。这在技术上不是递归。对time() 的第一次调用在第二次调用之前已经完成。您只是将第二次通话安排在未来一段时间。

标签: javascript recursion timer settimeout pass-by-value


【解决方案1】:

避免将字符串传递给setTimeout。当你这样做时,字符串或多或少地被执行为eval,这有很多原因是邪恶的。请参阅this question 了解更多信息。

请考虑将匿名函数传递给setTimeout。这将使解决您的问题变得微不足道:

t = setTimeout(function() { time(buf); }, 1000);

【讨论】:

    【解决方案2】:

    当您将字符串传递给setTimeout 时,它会在时机成熟时进行评估。在这种情况下,到时候,没有buf变量了,代码会抛出错误。

    您应该自己替换该值。

    t = setTimeout("time(" + buf + ")",1000);
    

    或者,更好的是,传递一个函数而不是字符串

    t = setTimeout(function() {
      time(buf);
    }, 1000);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-31
      • 2011-04-07
      • 1970-01-01
      • 1970-01-01
      • 2021-10-06
      • 2014-06-04
      相关资源
      最近更新 更多