编程小知识之 JavaScript 调用堆栈

49 篇文章 1 订阅

本文简述了几种在 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 中的输出如下:
image from https://code-maven.com/stack-trace-in-javascript

使用 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 下的输出:
image from https://code-maven.com/stack-trace-in-javascript

使用 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 的输出如下:
image from https://code-maven.com/stack-trace-in-javascript

参考资料
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值