2012-05-10 8 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内で衝突する2つの実行を防ぎ、実行するコードがmsecsより長くなければならない場合に同時に実行されます。 – glmxndr

+0

@subtenante:私は彼に 'setInterval()'の使用をどこで言いましたか?これは両方のケースの一般的なテキストです。私は 'setTimeout'を使ってその例を与えました。しかし、私はそれを明確にするために更新します。 – ThiefMaster

+0

@ThiefMaster私はコールバックを使用するコンセプトに感謝します。私は再帰的なルーチンにもっと熱心でした。 私が知っているから、それ自身を呼び出す関数は再帰です。どのようにそうではないと言いますか?再度、感謝します! – itsols

1

あなたのtimedCount()関数がそれ自身を呼び出していないので、再帰ではありません。を呼び出して、timeCount()を非同期にと呼ぶようにJSに要求しています。 setTimeout()(この場合は機能の終了)の後の行は、すぐに実行されます。タイムアウト後まで一時停止もスリープもしません。したがって、コードtimedCount()のどこか他の場所からtimedCount()を呼び出すと、実行が終了し、コードの他の部分に制御が戻り、タイムアウトを介して関数が再び呼び出されます。これにより、後でもう1つ実行するようにスケジュールされます(と同様に無限に)。実際の再帰があるように、もう1つが実行を完了するのを待つ途中で、途中で終了しています。timedCount()

あなたはこれをしなかった場合:

function timedCount() { 
    // other code here 

    timedCount(); 
} 

...その後ことが再帰になると、再帰を停止するように設定条件がないので、実際にクラッシュしていました。再帰がレベルの "合理的な"数を停止するようにいくつかの制御ロジックを追加しても問題ありません。

+0

私は非常に最初の答えでそれを理解しました。しかし、あなたの説明も良いです。 +1あなたの努力と時間です。ありがとう! – itsols