2013-06-13 27 views
5

私の頭の中で質問がどのように聞こえるかわからないので、私に同行してください。私は非同期プログラミングにはまったく新しいものです。そして、私は少しのJavaScriptのポンゲームを作ることを学ぶ最もよい方法を考え出しました。私はshootball()関数から始め、別のdivのdivをバウンスするだけです。私はこれはどのようにこのようなものであった。非同期JavaScriptの再帰

function shootball(angle, speed){ 
    angle = (angle/360.0)*2*Math.PI; 
    var ballmotion = setInterval(function(){ 
     var nowx, nowy, minusY, plusX; 
     nowx = $("#ball").position().left; 
     nowy = $("#ball").position().top; 
     minusY = Math.sin(angle) * 4.0; 
     plusX = Math.cos(angle) * 4.0; 
     if(hitsWall(nowx+plusX, nowy-minusY)){ 
      clearInterval(ballMotion); 
      shootball(newAngle(nowx+plusX, nowy-minusY), speed); 
     } 
     $("#ball").css("left", (nowx + plusX)).css("top", (nowy - minusY)); 
    }, 10/speed); 
} 

私は大きな不必要な再帰の大ファンではないんだけど、私はちょうどそれを試してみたかったです。わたしが予期していたとおり、それは正確に働く。しかし、プログラムの残りの部分を取り除き始めたとき、私はこの再帰的性質を避ける方法がないことが私にはありました。だから私の質問:javascriptどういうわけか、 "shootball"関数は、本質的にclearIntervalを呼び出した後に終了することを認識していますか?それとも、これは本当に自分のスタックに不必要なアクティベーションレコードをロードしているのでしょうか?どの専門知識にも事前に感謝しています。

+2

ブレークポイントを設定して呼び出しスタックを見ることができます;) –

+1

関数がその間隔よりも呼び出しに時間がかかる場合は、_setInterval_が厄介になり、代わりに_setTimeout_を使用することを検討してください。また、関数の大部分を式の外に移動して、新しい関数インスタンスが毎回作成されないようにすることができます。 –

+0

私は完全にはわかっていませんが、ボールが壁に当たっていないときはスタックが空になると信じています。 – aledujke

答えて

4

javascriptは、clearIntervalを呼び出した後、呼び出し元の "シュートボール"機能が本質的に終了していることを認識していますか?

いいえ、への割り当ての直後にshootballが終了しました。しかし、変数のスコープ(anglespeedballmotionと親スコープ)は、無名関数がそれを使ってクロージャを作成し、(スケジューラから)外部から参照されたために残っていました。そのスコープは、参照を削除したclearInterval呼び出しの後でガベージコレクションを取得します。

これは実際には不要なアクティベーションレコードをスタックにロードしていますか?

番号setTimeout/setIntervalで実行されるすべての関数は、新しい呼び出しスタックを使用して、独自の実行コンテキストで実行されます。

+0

一部のブラウザでは、ページが実行されている限り、すべての変数を有効に保つため、変数をクリアする必要はありません。 –

+0

@Derek:ブラウザによっては、「clearInterval」のガベージコレクションが失敗することがありますか? – Bergi

+0

私はそれが標準で書かれているとは思わないので、ブラウザは無用な変数を必ずしも明確にする必要がないので、わかりません。 –

関連する問題