我正在查看w3schools网页工作者页面,并注意到此代码:
var i=0;
function timedCount()
{
i=i+1;
postMessage(i);
setTimeout("timedCount()",500);
}
timedCount();
两个问题:
我还不完全了解递归函数的本质,但我记得每次递归调用都存储在内存中。这适用于所有递归函数吗?如果它运行的时间足够长,那么该函数最终会阻塞内存吗?
谢谢!
答案 0 :(得分:4)
这是不递归,因为timedCount
在调用下一个实例之前退出。
它只是一个自我延续的延迟循环,如果你想称之为。 (顺便说一下,使用setInterval
处理得更好,而不是重复使用setTimeout
。这个例子是一些非常糟糕的代码,就像大多数W3Fools资源一样。)
timedCount() -> setTimeout() -> end
^ |
| |
+----------------+
此是一个递归函数:
function recurse() {
recurse();
}
这里建立了一个调用堆栈,外部recurse
将不会退出并离开堆栈,直到内部recurse
调用返回,直到它的内部recurse
调用返回等无限期。由于这里任何地方都没有return
,所以这最终会炸掉堆栈;所以有资源使用。
recurse() -> recurse() -> recurse() -> recurse() -> recurse() -> ...
答案 1 :(得分:2)
一般来说,递归可以优化,但你可以放心地假设javascript实现没有为递归优化。
关于你的两个具体问题:
timedCount的重要之处在于它在返回之前无法再次调用。 无视并行性。
答案 2 :(得分:1)
每个功能都在内存中。
真正的递归函数会为每次调用消耗堆栈空间(就像其他所有函数一样),重要的是它会递送多少次次。
我不认为这个示例是“递归的”,因为timedCount
的原始调用在计时器到期后再次调用之前结束。如果它看起来像这样:
function timedCount() {
i = i + 1;
postMessage(i);
timedCount();
}
这是递归的,因为没有终止条件,所以会非常快地炸掉你的筹码。