有没有办法在javascript中动态查看调用堆栈?

时间:2011-03-13 11:06:20

标签: javascript html5

一般性问题,但有问题的代码是:

有一个错误例程被抛出 - 处理exeptions:

MyObj.prototype.err = function( msg ) { ... throw(msg); }

所以扔,

if( mybad ) this.err( 'my message' );

希望err()的行为不同,具体取决于函数是否在调用堆栈中。

例如,

可能是

funcA() -> func2() -> func3() -> err()

funcB() -> func3() -> err()

如果funcA在上游,想提醒用户并停止;而如果是funcB,想将消息写入控制台并继续。

实现解决问题的其他方法,但是创造(和维护)可以从环境中推断出的状态空间的运气不好

2 个答案:

答案 0 :(得分:0)

在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);
  }
};

尝试理解为什么这是更好的解决方案,它是关于定义哪些功能属于哪个功能的责任。这正是异常和处理按原样设计的原因。

答案 1 :(得分:0)

我不确定你要解决的是什么,但我很确定有更好的方法来做到这一点。

话虽这么说,这是一种跟踪函数和检查callstack而不需要解析特定于浏览器的堆栈跟踪的方法:

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/