编程小知识之 JavaScript 调用堆栈

本文简述了几种在 JavaScript 中获取调用堆栈(call stack)的方法

使用 console.trace

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 中的输出如下:

使用 Error 对象

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

通过使用 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 的输出如下:

参考资料

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券