2011-12-05 30 views
7

有沒有一種方法可以確定使用javascript本身在JavaScript中執行的所有函數的堆棧深度?javascript中使用javascript確定堆棧深度

我在想這可能涉及到修改Function原型,但我真的不知道。

此外,如果能夠在堆棧深度足夠高的時候破解,那將是非常好的。

原因是我有一個stack overflow error in IE which is apparently not debuggable。我很懶,我寧願不必通過我要維護的代碼來尋找原因。

感謝您協助我的懶惰。

+0

你可以告訴一個函數到另一個函數並增加一個全局變量,直到瀏覽器本身拋出一個堆棧溢出錯誤。然後你打印你的計數器變量,並且你有一個堆棧深度的粗略值。 – Bojangles

回答

5

ECMAscript支持相當一段時間的Function.prototype.caller屬性。即使它在ES5中被棄用,IE仍應該支持它。所以你可以基本上通過所涉及的功能循環。

function one() { 
    two(); 
} 

function two() { 
    three(); 
} 

function three() { 
    var caller = three.caller; 

    console.log('caller was: ', caller.name); 

    while(caller = caller.caller) { 
      console.log('caller was: ', caller.name); 
    } 
} 

(function outer() { 
    one(); 
}()); 

將輸出:

caller was: two 
caller was: one 
caller was: _outer 

所以,如果你知道在哪個功能的錯誤發生,這樣你得到的答案這個方法瞭如何原名一路。如果您剛好在深度之後,則可以只計算在caller.caller屬性上進行了多少次交易。至少IE8應該支持「調試器」語句,您可以在該腳本中調用該語句以將調試器帶入舞臺。

+0

這看起來很像我要做的事情......但事情是我需要以某種方式將它應用於所有功能,而無需將其添加到其代碼中。你懂我的意思嗎?謝謝。 – user420667

+1

@ user420667:我認爲在Function.prototype上沒有任何「簡單」的方法。你基本上需要對所有對象進行遞歸循環(以'window'開始)並檢查函數。如果你找到了一個,你需要鉤住/修補方法並調用上面提供的代碼。可能工作。 – jAndy

+0

哦,好吧..所以像每個函數... newFunction = function(){oldFunction(args);如果(CallerDepth()> MaxAllowedDepth){debugger;}}; oldFunction = newFunction; ???我不'認爲這是正確的。此外,就像你所說的,確保以某種方式在任何其他函數之前被調用,並且確保在修改任何函數之前創建要遍歷的函數列表。 – user420667

4
function stackDepth() { 
    var c=stackDepth.caller, depth=0; 
    while (c) { c = c.caller; depth++; } 
    return depth; 
} 

鉻似乎認爲,從控制檯的堆棧深度已經是3,所以也許每個JavaScript環境你需要確定初始基線深度和從減法。

stackDepth(); // => 3 
(function(){return stackDepth();})(); // => 4 
+0

有趣。我想知道3個更高級別的對象是什麼。窗口?文件? – user420667