以下代码段演示了使用 JavaScript 的递归调用。
function timedCount()
{
document.getElementById('txt').value=c;
c=c+1;
t=setTimeout("timedCount()",1000);
}
来源来自这里。
我的问题:这不会导致堆栈堆积并随后导致堆栈溢出吗?我知道这肯定会在 Pascal 和 C/C++ 等语言中崩溃。
感谢您对此的任何建议。
以下代码段演示了使用 JavaScript 的递归调用。
function timedCount()
{
document.getElementById('txt').value=c;
c=c+1;
t=setTimeout("timedCount()",1000);
}
来源来自这里。
我的问题:这不会导致堆栈堆积并随后导致堆栈溢出吗?我知道这肯定会在 Pascal 和 C/C++ 等语言中崩溃。
感谢您对此的任何建议。
这不是真正的递归,因此不会创建深度调用堆栈。
但是,您永远不应该将字符串传递给setInterval()
or setTimeout()
。这样做和使用一样糟糕,eval()
一旦你使用变量,它就会导致潜在的不可读和不安全的代码,因为你需要将它们插入字符串而不是传递实际变量。
正确的解决方案是setTimeout(function() { /* your code *) }, msecs);
。这同样适用于setInterval()
。如果只想调用单个函数不带任何参数,也可以直接传递函数名:(setTimeout(someFunction, msecs);
注意函数名后面没有) ()
所以在你的情况下,使用t = setTimeout(timedCount, 1000);
那不是递归,因为您的timedCount()
函数不是在调用自己,而是在调用setTimeout()
以要求 JS在指定的延迟后timeCount()
异步调用。后面的行setTimeout()
- 在这种情况下只是函数的结尾 - 将立即执行,直到超时之后它才会暂停或休眠。因此,当您timedCount()
从代码中的其他位置调用时,您的代码timedCount()
将完成执行并且控制权将返回到代码的其他部分,然后稍后将通过超时再次调用该函数,这再次导致另一个函数被安排在以后执行(并且以此类推,无止境)。在任何时候都timedCount()
不会像实际递归那样等待另一个完成执行。
如果你这样做:
function timedCount() {
// other code here
timedCount();
}
...那么这将是递归并且确实会崩溃,因为没有设置条件来停止递归。如果您添加一些控制逻辑,以便递归停止“合理”数量的深度,那就没问题了。