有没有办法在javascript中动态查看调用堆栈?
问题描述:
一个一般性的问题,但有问题的代码是这样的:有没有办法在javascript中动态查看调用堆栈?
有被抛出一个错误例程 - 处理产生的异常:
MyObj.prototype.err = function(msg) { ... throw(msg); }
这么扔,
if(mybad) this.err('my message');
想根据函数是否在调用堆栈中,err()的行为有所不同。
例如,可以是
funcA() -> func2() -> func3() -> err()
与
funcB() -> func3() -> err()
如果FuncA的行是上游,想以提醒用户和停止;而如果funcB想将消息写入控制台并继续。
实现其他的方式来解决问题,但恕我直言运气不好创建(和维护),可以从环境中推断
答
在Chrome中,你可以做状态空间:
var err = function(msg) {
// ...
var error = new Error();
var stack = error.stack;
// Do some string manipulation with stack
// mayThrow = 'funcB is in stack'
if (mayThrow) {
throw(msg);
}
};
我可以指出我认为这是一个非常不好的做法。我认为你应该赶上FuncB
中的错误,而不是将FuncB
定义为不从err
中抛出的函数。这是更少的代码,更容易管理。所以:
var err = function(msg) {
// ...
throw(msg);
};
var func3 = function() {
// ...
err('Double rainbow');
};
var funcB = function() {
try {
func3();
catch(e) {
console.log(e);
}
};
试图理解为什么这是更好的解决方案,它是关于界定责任,其功能属于哪个功能。这正是为什么异常和处理的设计方式。
答
我不确定你想要解决什么问题,但我很肯定有一个更好的方法来做到这一点。
话虽这么说,这里的追踪功能,并检查调用栈,而不诉诸特定浏览器的堆栈跟踪的分析的一种方法:
var callstack = [];
function traced(name, func) {
return function() {
callstack.push(name);
func.apply(this, arguments);
callstack.pop();
}
}
,并使用它像这样:
var a = traced("a", function() {
b();
});
var b = traced("b", function() {
c();
});
var c = traced("c", function() {
var s = callstack.join("<br>");
document.getElementById('output').innerHTML = s;
});
document.getElementById('a').onclick = a;
document.getElementById('b').onclick = b;
你可以在此处查看:http://jsfiddle.net/AsrSp/
+1分享您的体验:“运气不佳(可以推导出)并且可以推导出状态空间” – 2011-03-13 11:15:20
[这里](http://eriwen.com/javascript/stacktrace-update/)是一篇有趣的博文。然而,因为我同意你的最后一句话,这看起来像是一种“不幸运”的方式,而且肯定会很慢。 – Pointy 2011-03-13 11:16:53