2009-10-08 24 views
0

我有以下代碼示例來說明我的觀點。當我加載此在IE8在Vista上我得到的錯誤「堆棧Overfow在行:16」使用Javascript類函數執行15次遞歸後的堆棧溢出

如果我改乘使用頂級函數(TestClass的對象外)我可以遞歸數百萬次無堆棧溢出。

這是怎麼發生的?最終,我只是實現了一個Function Que,而不是使用遞歸,但對我來說沒有意義,我想了解原因。

- 代碼 -

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"> 
<html> 
    <head> 
     <title>Recusion Test</title> 
     <body> 
     </body> 

     <script type="text/javascript"> 

      function testClass() { 
       this.x = 15; 
       this.recurse = function() { 
        this.x--; 
        this.recurse(); 
       } 
      } 

      var wtf = new testClass(); 
       wtf.recurse(); 

      alert('done'); 
     </script> 
    </head> 
</html> 
+0

好的,這是我的一個錯誤,我簡化了一個複雜的類用於演示目的,我忘了包括它。請參閱下面的答案。在我的實際代碼庫中,我能夠在沒有SO的情況下遞歸14次,但在15時它會失敗。 – 2009-10-08 21:29:05

回答

7

沒有爲您的遞歸語句,因此它會永遠運行沒有終止條件。

看樣子,你想...


      function testClass() { 
       this.x = 15; 
       this.recurse = function() { 
        if (this.x--) 
         this.recurse(); 
       } 
      } 

      var wtf = new testClass(); 
       wtf.recurse(); 

      alert('done'); 
1

好吧,這裏的一些更深入地瞭解我是有這個問題。在回到我的應用程序並修復了我認爲的問題後,我仍然遇到了這個問題。讓我追求這個問題的部分是,如果我遞歸只有14次,它會成功完成。

首先,我在HTA中執行原始代碼,而不是Internet Explorer。我正在編寫一個類似於FCKEditor的基於VIM的代碼編輯器。

其次,我的代碼的結構如下:

-HTA

--EditorClass

--- DivManagerClass

---- KeyBindingClass

在我的KeyBindingClass我有一個類似於提供的例子的代碼庫(除了它有一個終止條件)

在我的KeyBindingClass中,我有一個repeater屬性,如果按下數字修飾符,它將重複最後一次keystrok N次。對於那些不知道在vim中以可視模式按鍵'3'和'x'的人,會刪除三個字符。直到我用一個數值修改超過14

我一直試圖重現此問題的一個小測試工具,並不能

,一切運行良好。我能夠在基本測試工具中遞增到3000。所以我開始重新創建場景,盡我所能。首先,我將調用轉移到另一個類/方法的遞歸方法。這限制了我的調用堆棧大約在1600左右(幾乎一半的堆棧消失了)。

然後我將jQuery添加到混合中,並將調用移動到ParentClass.recurse方法中,並放入document.onready jquery handler中的鍵綁定事件。這減少了我的調用堆棧大約1300.

然後我將我的代碼移到一個HTA中,將我的調用堆棧再次削減一半!儘可能地模仿我的代碼庫後,我可以儘可能快地到達大約515的調用堆棧。

在做了一些研究後,我發現IE使用可用的內存空間來確定調用堆棧的大小。我猜測HTA在這方面有點嚴格。我還沒有弄清楚在給定類結構的情況下,其他因素限制了我的應用程序到如此低的調用堆棧,但這絕對是代碼結構。

我可以將我的基本遞歸測試放在頂層執行腳本標記中,並在達到堆棧溢出之前獲得大約1473個調用。

我仍然可以使用函數隊列來解決我的問題,但我只是想讓其他人知道答:我不會在Stack Overflow中發佈這樣一個簡單的問題,並且B.您的調用堆棧限制可能會很大受到圍繞函數的類結構的影響,即使它們不是傳統上認爲函數堆棧的單獨級別。