JavaScript中递归的作用

JavaScript中递归的作用,javascript,recursion,stack-overflow,Javascript,Recursion,Stack Overflow,下面的代码段演示了使用JavaScript的递归调用 function timedCount() { document.getElementById('txt').value=c; c=c+1; t=setTimeout("timedCount()",1000); } 来源于 我的问题:这是否会导致堆栈堆积,并随后导致堆栈溢出?我知道,在Pascal和C/C++等语言中,这肯定会崩溃 谢谢你的建议。这不是真正的递归,因此不会创建深层调用堆栈 但是,您应该永远不要将字符串传递给setInter

下面的代码段演示了使用JavaScript的递归调用

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

我的问题:这是否会导致堆栈堆积,并随后导致堆栈溢出?我知道,在Pascal和C/C++等语言中,这肯定会崩溃


谢谢你的建议。

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


但是,您应该永远不要将字符串传递给
setInterval()
setTimeout()
。这样做与使用
eval()
一样糟糕,而且一旦使用变量,可能会导致代码不可读,甚至不安全,因为您需要将变量插入字符串中,而不是传递实际变量

正确的解决方案是
setTimeout(function(){/*您的代码*)},毫秒)。这同样适用于
setInterval()
。如果只想不带任何参数调用单个函数,也可以直接传递函数名:
setTimeout(someFunction,毫秒)(请注意,函数名后面没有
()


因此,在您的情况下,使用
t=setTimeout(timedCount,1000)

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


但是,您应该永远不要将字符串传递给
setInterval()
setTimeout()
。这样做与使用
eval()
一样糟糕,而且一旦使用变量,可能会导致代码不可读,甚至不安全,因为您需要将变量插入字符串中,而不是传递实际变量

正确的解决方案是
setTimeout(function(){/*您的代码*)},毫秒)。这同样适用于
setInterval()
。如果只想不带任何参数调用单个函数,也可以直接传递函数名:
setTimeout(someFunction,毫秒)(请注意,函数名后面没有
()


因此,在您的情况下,使用
t=setTimeout(timedCount,1000)

这不是递归,因为您的
timedCount()
函数没有调用自身,它正在调用
setTimeout()
,要求JS在指定延迟后异步调用
timeCount()
。带有
setTimeout()
的那一行后面的那一行—在本例中,它只是函数的结尾—将立即执行,直到超时之后才暂停或休眠。因此,当您从代码中的其他地方调用
timedCount()
时,
timedCount()
将完成执行,控制将返回到代码的另一部分,然后稍后将通过超时再次调用该函数,这将再次导致安排另一个函数稍后执行(如此类推)。在任何时候都不会有一个完成了一半的
timedCount()
等待另一个完成执行,就像实际递归一样

如果您这样做:

function timedCount() {
   // other code here

   timedCount();
}

…那么这将是递归,并且确实会崩溃,因为没有设置停止递归的条件。如果您添加一些控制逻辑,以便递归停止一个“合理”数量的深度级别,这将很好。

这不是递归,因为您的
timedCount()
函数没有调用自身,它调用的是
setTimeout()
,要求JS在指定延迟后异步调用
timeCount()
。带有
setTimeout()
的那一行后面的那一行—在本例中,它只是函数的结尾—将立即执行,直到超时之后才暂停或休眠。因此,当您从代码中的其他地方调用
timedCount()
时,
timedCount()
将完成执行,控制将返回到代码的另一部分,然后稍后将通过超时再次调用该函数,这将再次导致安排另一个函数稍后执行(如此类推)。在任何时候都不会有一个完成了一半的
timedCount()
等待另一个完成执行,就像实际递归一样

如果您这样做:

function timedCount() {
   // other code here

   timedCount();
}

…那么这将是递归,并且确实会崩溃,因为没有设置停止递归的条件。如果您添加一些控制逻辑,以便递归停止一个“合理”的深度级别数,那就可以了。

这是不对的。这两件事做的不一样。setInterval将在每次调用之间强制执行毫秒的时间,但伪递归setTimeout将防止两次执行在毫秒内发生冲突,如果要执行的代码的持续时间必须超过毫秒,则可能导致多次同时执行。@Subtenant:我在哪里告诉他使用
setInterval()
?!这是两种情况下的通用文本,我甚至用
setTimeout
给他举了一个例子。但是我会更新它,使它更清晰。@ThiefMaster我很欣赏使用回调的概念。我更热衷于递归程序。据我所知,函数调用本身就是递归。你怎么说不是?再次感谢@itsols:函数不调用自身。它计划自己被称为asynchronously@itsols函数没有调用自身,而是将自身传递给setTimeout,以便稍后由其他对象调用。这是不对的。这两件事做的不一样。setInterval将在每次调用之间强制执行毫秒的时间,但伪递归setTimeout将防止两次执行在毫秒内发生冲突,如果要执行的代码的持续时间必须超过毫秒,则可能导致多次同时执行。@Subtenant:我在哪里告诉他使用
setInterval()
?!这是两种情况下的通用文本,我甚至用
setTimeout
给他举了一个例子。但是我会更新它,使它更清晰。@ThiefMaster我很欣赏使用回调的概念。我更热衷于递归溃败