以下代碼段演示了使用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