本文简述了几种在 JavaScript 中获取调用堆栈(call stack)的方法
console 支持 trace 方法,使用该方法可以向控制台输出当前的调用堆栈.
示例代码如下:
// logging_trace.js
function add(x, y) {
console.trace('add called with ', x, 'and', y);
return x + y;
}
function calc() {
return add(8, 11) + add(9, 14);
}
function main() {
var x = add(2, 3);
var y = calc();
}
main();
Chrome 中的输出如下:
console.trace 只能向控制台输出调用堆栈,我们并不能直接获取到调用堆栈的数据,但借助 Error,我们便可以直接获取当前的调用堆栈了,方法就是访问 Error 对象的 stack 属性:
// logging_trace_with_error.js
function add(x, y) {
console.log(new Error().stack);
return x + y;
}
function calc() {
return add(8, 11) + add(9, 14);
}
function main() {
var x = add(2, 3);
var y = calc();
}
main();
同样给出 Chrome 下的输出:
通过使用 arguments 的 callee 和 callee.caller,我们可以逐级查找上一层的调用函数,调用堆栈也就可以得到了.
示例代码稍有些复杂,使用了递归,有兴趣的朋友可以仔细看看:
// logging_stacktrace.js
function add(x, y) {
console.log(stacktrace());
return x + y;
}
function calc() {
return add(8, 11) + add(9, 14);
}
function main() {
var x = add(2, 3);
var y = calc();
}
function stacktrace() {
function st2(f) {
var args = [];
if (f) {
for (var i = 0; i < f.arguments.length; i++) {
args.push(f.arguments[i]);
}
// substring(9) here to get rid of "function " prefix
var function_name = f.toString().split('(')[0].substring(9);
// recur to get previous caller
return st2(f.caller) + function_name + '(' + args.join(', ') + ')' + "\n";
} else {
return "";
}
}
return st2(arguments.callee.caller);
}
main();
Chrome 的输出如下: