2013-12-23 52 views
3

我正在閱讀關於遞歸函數我讀過,當我們使用遞歸函數時,它調用一個堆棧幀,所以如果我們最終調用遞歸函數10000次,它可能是一個可用內存的問題。我在下面有一個函數是正確的使用遞歸?或者你認爲我應該避免它?何時使用遞歸函數?

function animateLeft(obj, top){ 
    if(top >= 300){   
     obj.style.visibility = 'visible'; 
     return; 
    } 
    else { 
     var box = obj; 
     box.style.marginLeft = top + "px"; 
     box.style.marginTop = top + "px"; 
     setTimeout(function(){ 
      animateLeft(obj, top + 1); 
     }, 25) 
    } 
} 
function animateMe() { 
    animateLeft(document.getElementById('inner-rectange'), 0); 
} 
+0

我有問題,並且我用遞歸來解決它們。 – corsiKa

+1

指出這個問題可以在純CSS中解決可能是有用的 – Simone

+0

@simone我想創建一個動畫,所以我必須添加延遲不知道如何使用css – Jay

回答

3

你是不是真的使用遞歸,因爲你調用從setTimeout方法。

通過功能的時間重新執行初始將已經退出。(每個執行不會阻止未來)在JavaScript的事情,操作DOM是錯誤的

使用遞歸,因爲重繪只有在整個遞歸完成後纔會出現頁面。因此,您將失去動畫的所有中間步驟,並從第一步開始到最後一步。


正如評論提到的問題,你可以實現這種單獨CSS動畫..

只需通過CSS設置DOM節點的transition property,然後通過應用新更改的屬性類(或直接通過JavaScript

div{ 
    margin-left:0; 
    margin-top:0; 

    -moz-transition:margin 2s linear; 
    -webkit-transition:margin 2s linear; 
    transition:all 2s linear; 
} 

.move{ 
    margin-left:100px; 
    margin-top:100px; 
} 

見演示在http://jsfiddle.net/gaby/rm3EP/

當你申請的move類的div CSS動畫將在利潤率的變化..

+0

那麼這是否意味着遞歸函數涉及到背景,而settimeout有延遲? – Jay

+1

根據定義的超時超時會在您指定的時間過後(*且不阻止其他代碼執行*)後調用回調*** –

+0

ok如果刪除setTimeout函數,會發生什麼情況?它會是遞歸的而不是正確的? – Jay

1

我不會使用遞歸來做到這一點。我甚至不確定這是不是通過jQuery或其他方式做得更好。

我認爲遞歸首先在處理像樹這樣的遞歸數據結構時,而不是像這樣的情況。

+0

或者多維數組對象或其他東西 –

5

使用setTimeout意味着您的代碼不是直接遞歸調用動畫函數。這將導致該函數被重複調用,但不會導致創建深度堆棧。

對於一個動畫這是一個相當合理的方法(有更好的方法,如​​,但它是合理的!)

+0

其試圖創建settimeout的動畫只會增加延遲。 – Jay

+0

@jay看看http://underscorejs.org/#defer – spojam

+0

我不認爲這是ABA遞歸,因爲堆棧永遠不會有多次相同的A函數。使用'setTimeout'這種方式只是意味着函數會被一次又一次地調用,但從來沒有從它本身(或它調用的某個函數 - 這會產生一個ABA遞歸) – Toote

0

你舉的例子更是一個延遲resursive功能。由於setTimeout,內存應該沒有問題。目前animateLeft將會完成,接下來將會完成。

0

我知道這是遲到,但我一直在尋找最近的遞歸函數。 我最好的答案是,只有當你不知道你需要運行一段代碼或者當你有某些類型的數據結構(如樹或 堆棧)時,才使用遞歸函數