2010-01-13 81 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)

相关问题