2010-01-13 87 views
18

對於簡單的JavaScript調試,我將使用警報顯示變量值等。有沒有辦法讓JavaScript中的當前調用堆棧能夠顯示在警報中?調試javascript時,有沒有辦法提醒當前的調用堆棧?

謝謝。

+0

這是用於調試或生產?我不確定在所有瀏覽器中都有這樣的標準方式,但是可能會有一些有用的功能僅適用於某些瀏覽器... – 2010-01-13 21:20:31

+0

這只是爲了調試目的。 – rosscj2533 2010-01-13 21:25:53

回答

36

快速和骯髒的基於Gecko的瀏覽器:

new Error().stack 

您也可以使用手動Function.prototype.caller蒐羅一些堆棧:

var thisFunction = arguments.callee; 
var caller = thisFunction.caller; 
var callerCaller = caller.caller; 
// ...and eventually, assuming no recursion: 
var bottomCaller = ...; 
assert(bottomCaller.caller === null); 

.caller技巧的一個(可能很大)的警告是,它不處理遞歸 - .caller看起來從棧頂downwar d在堆棧中查找函數的第一個實例,然後返回它的直接調用者,所以不需要小心,你可以循環無限地查找調用者。

另一個告誡caller的是,展望未來,如果你的任何代碼使用的ECMAScript 5的嚴格模式,(這已經自己從嚴格模式函數調用或功能)嚴格模式功能caller屬性是所謂所謂的「毒藥丸」在訪問時拋出TypeError。 「綁定」功能(由ES5的Function.prototype.bind方法創建的那些)的屬性caller也是一種毒藥。這些限制破壞了通用的棧走算法,儘管可以想象使用特定的方法來解決這個問題(可能是進入和退出註釋函數)。

請注意,像這樣的棧走並不是生產代碼中的一個好主意(作爲一個快速的黑客來調試它很好,壽);在Mozilla的JS引擎中,像在後面的例子中一樣走棧時,它可能會讓你退出機器代碼並返回到解釋代碼中。此外,堆棧走線是O(如果您傾向於擁有複雜的深層堆棧,則這可能很重要)。

+0

謝謝,這是關於我在找什麼。 – rosscj2533 2010-01-14 18:44:09

+0

這個答案今天仍然相關嗎? – naaz 2017-07-29 01:01:06

+0

堆棧走並不像以前那麼昂貴,但它仍然會傷害到一定程度的性能。在最近的ECMAScript版本中,毒丸屬性函數的一些更精細的細節已經發生了變化,但總的推力大部分是相同的。除了這兩點之外,我認爲評論仍然具有根本性的相關性。 – 2017-10-04 18:46:39

6

如果您使用Firefox,請使用像Firebug這樣的調試器。 Chrome和Opera有內置調試器。 Internet Explorer有Developers Tools

+0

謝謝,我知道這些選項,但我想知道是否有一種方法可以不使用調試器。 – rosscj2533 2010-01-13 21:10:47

+2

IMO調試javascript的最簡單和最快捷的方法是使用調試器。 – 2010-01-13 21:13:38

+0

使用調試器是沒有問題的,而且通常很方便,我只是想在正確的情況下查找調用堆棧。 – rosscj2533 2010-01-14 18:45:43

3

調試Javascript的最佳方式是使用Firebug,其中包括一個完整的Javascript調試器。

如果您在IE中進行調試,您可以使用Visual Web Developer Express(或任何其他版本的Visual Studio)。
如果您正在調試IE8,您可以使用其內置的開發人員工具,其中包括一個調試器。

可以在Javascript中獲得調用堆棧;見here

3

你看過螢火蟲 - 還有一個斷點。如果只是爲了調試,那麼這可能就足夠了。

而且 - 你可以看看Here

20

在Firefox + Firebug的和WebKit你可以使用console.trace()

它不會顯示alert()但在控制檯上打印stacktrace

+0

正是我正在尋找。如果要在加載頁面時轉儲調用堆棧,這一點尤其有用。 – 2013-02-05 21:07:28

+0

這應該是正確的答案 – Ziarno 2014-08-12 09:25:14

+0

謝謝!我不知道這個竅門。 – kris 2015-05-06 04:52:17

1

這會給你所有調用堆棧 對我很好。

var y = 'arguments.callee.caller'; 
    while (eval(y) != undefined) { 
     stak += eval(y + '.toString()'); 
     y = y + '.caller'; 
    } 
    alert(stak); 
0

對於調試的NodeJS,在Visual Studio代碼,v.1.14.2,它的視圖 - >調試(按Ctrl + Shift + d)

相關問題