2012-05-10 68 views
0

以下代码段演示了使用JavaScript的递归调用。JavaScript中的递归效果

function timedCount() 
{ 
document.getElementById('txt').value=c; 
c=c+1; 
t=setTimeout("timedCount()",1000); 
} 

该来源是从here

我的问题:这不会导致堆栈建立和随后的堆栈溢出吗?我知道一个事实,这肯定会在像Pascal和C/C++这样的语言中崩溃。

感谢您对此的任何建议。

回答

2

这不是真正的递归,因此不会创建深层调用堆栈。


然而,你应该永远传递一个字符串,setInterval()setTimeout()。这样做与使用eval()一样糟糕,只要使用变量,就会导致潜在的不可读和可能不安全的代码,因为您需要将它们插入到字符串中,而不是传递实际变量。

适当的解决方案是setTimeout(function() { /* your code *) }, msecs);。这同样适用于setInterval()。如果你只是想调用一个函数不带任何参数,您也可以直接传递函数名:setTimeout(someFunction, msecs);(注意有没有()函数名后)

所以你的情况,使用

+0

这是不对的。两件事情都不一样。 setInterval将在每次调用之间强制执行一个msecs时间,但伪递归setTimeout将防止两次执行在msecs内发生冲突,如果要执行的代码的持续时间必须超过msecs,则可能会导致多个同时执行。 – glmxndr

+0

@subtenante:我在哪里告诉他使用'setInterval()'?!这是两种情况下的通用文本,我甚至用“setTimeout”给了他一个例子。但我会更新它以使其清晰。 – ThiefMaster

+0

@ThiefMaster我很欣赏使用回调的概念。我更加热衷于递归程序。 从我所知道的,一个调用自己的函数是递归。你怎么说这不是?再次感谢! – itsols

1

这不是递归,因为你的timedCount()功能不调用本身,它呼吁setTimeout()问JS调用timeCount()异步指定的延迟之后。 setTimeout()之后的行(在这种情况下仅仅是函数的结尾)将立即执行,它不会暂停或休眠,直到超时。因此,当您在代码timedCount()中的其他地方拨打timedCount()将完成执行并且控制将返回到您的代码的其他部分,则稍后该函数将再次通过超时被调用,这又会导致另一个被调度以供稍后执行(等无限广告)。在任何时候都没有中途完成timedCount()等待另一个完成执行,就像实际递归一样。

如果你这样做:

function timedCount() { 
    // other code here 

    timedCount(); 
} 

...然后将递归和的确会崩溃,因为没有设定停止递归的条件。如果你添加一些控制逻辑,以便递归停止一个“合理”的深度级别,那很好。

+0

我想到了我收到的第一个答案。但你的解释也很好。 +1为您的努力和时间。谢谢! – itsols