以下代码段演示了使用JavaScript的递归调用。JavaScript中的递归效果
function timedCount()
{
document.getElementById('txt').value=c;
c=c+1;
t=setTimeout("timedCount()",1000);
}
该来源是从here。
我的问题:这不会导致堆栈建立和随后的堆栈溢出吗?我知道一个事实,这肯定会在像Pascal和C/C++这样的语言中崩溃。
感谢您对此的任何建议。
以下代码段演示了使用JavaScript的递归调用。JavaScript中的递归效果
function timedCount()
{
document.getElementById('txt').value=c;
c=c+1;
t=setTimeout("timedCount()",1000);
}
该来源是从here。
我的问题:这不会导致堆栈建立和随后的堆栈溢出吗?我知道一个事实,这肯定会在像Pascal和C/C++这样的语言中崩溃。
感谢您对此的任何建议。
这不是真正的递归,因此不会创建深层调用堆栈。
然而,你应该永远传递一个字符串,setInterval()
或setTimeout()
。这样做与使用eval()
一样糟糕,只要使用变量,就会导致潜在的不可读和可能不安全的代码,因为您需要将它们插入到字符串中,而不是传递实际变量。
适当的解决方案是setTimeout(function() { /* your code *) }, msecs);
。这同样适用于setInterval()
。如果你只是想调用一个函数不带任何参数,您也可以直接传递函数名:setTimeout(someFunction, msecs);
(注意有没有()
函数名后)
所以你的情况,使用
这不是递归,因为你的timedCount()
功能不调用本身,它呼吁setTimeout()
问JS调用timeCount()
异步指定的延迟之后。 setTimeout()
之后的行(在这种情况下仅仅是函数的结尾)将立即执行,它不会暂停或休眠,直到超时。因此,当您在代码timedCount()
中的其他地方拨打timedCount()
将完成执行并且控制将返回到您的代码的其他部分,则稍后该函数将再次通过超时被调用,这又会导致另一个被调度以供稍后执行(等无限广告)。在任何时候都没有中途完成timedCount()
等待另一个完成执行,就像实际递归一样。
如果你这样做:
function timedCount() {
// other code here
timedCount();
}
...然后是将递归和的确会崩溃,因为没有设定停止递归的条件。如果你添加一些控制逻辑,以便递归停止一个“合理”的深度级别,那很好。
我想到了我收到的第一个答案。但你的解释也很好。 +1为您的努力和时间。谢谢! – itsols
这是不对的。两件事情都不一样。 setInterval将在每次调用之间强制执行一个msecs时间,但伪递归setTimeout将防止两次执行在msecs内发生冲突,如果要执行的代码的持续时间必须超过msecs,则可能会导致多个同时执行。 – glmxndr
@subtenante:我在哪里告诉他使用'setInterval()'?!这是两种情况下的通用文本,我甚至用“setTimeout”给了他一个例子。但我会更新它以使其清晰。 – ThiefMaster
@ThiefMaster我很欣赏使用回调的概念。我更加热衷于递归程序。 从我所知道的,一个调用自己的函数是递归。你怎么说这不是?再次感谢! – itsols