function main()
{
   Hello();
}

function Hello()
{
  // How do you find out the caller function is 'main'?
}

有办法找到调用堆栈吗?


当前回答

我可以在2021年使用这些,并获得从调用者函数开始的堆栈:

1. console.trace();
2. console.log((new Error).stack)

// do the same as #2 just with better view
3. console.log((new Error).stack.split("\n")) 

其他回答

堆栈跟踪

您可以使用特定于浏览器的代码找到整个堆栈跟踪。好在已经有人成功了;这是GitHub上的项目代码。

但并非所有的消息都是好消息:

It is really slow to get the stack trace so be careful (read this for more). You will need to define function names for the stack trace to be legible. Because if you have code like this: var Klass = function kls() { this.Hello = function() { alert(printStackTrace().join('\n\n')); }; } new Klass().Hello(); Google Chrome will alert ... kls.Hello ( ... but most browsers will expect a function name just after the keyword function and will treat it as an anonymous function. An not even Chrome will be able to use the Klass name if you don't give the name kls to the function. And by the way, you can pass to the function printStackTrace the option {guess: true} but I didn't find any real improvement by doing that. Not all browsers give you the same information. That is, parameters, code column, etc.

调用方函数名

顺便说一下,如果你只想要调用函数的名称(在大多数浏览器中,但不是IE),你可以使用:

arguments.callee.caller.name

但是请注意,这个名称将位于function关键字之后。我发现没有办法(甚至在谷歌Chrome上)在没有得到整个函数的代码的情况下得到更多。

调用方函数码

并总结了其他最好的答案(作者:Pablo Cabrera, nourdine和Greg Hewgill)。你可以使用的唯一跨浏览器且真正安全的东西是:

arguments.callee.caller.toString();

它将显示调用方函数的代码。遗憾的是,这对我来说还不够,这就是为什么我给你关于StackTrace和调用者函数Name的提示(尽管它们不是跨浏览器的)。

对我来说很好,你可以在函数中选择你想要返回的程度:

function getCaller(functionBack= 0) {
    const back = functionBack * 2;
    const stack = new Error().stack.split('at ');
    const stackIndex = stack[3 + back].includes('C:') ? (3 + back) : (4 + back);
    const isAsync = stack[stackIndex].includes('async');
    let result;
    if (isAsync)
      result = stack[stackIndex].split(' ')[1].split(' ')[0];
    else
      result = stack[stackIndex].split(' ')[0];
    return result;
}
function main()
{
   Hello();
}

function Hello()
{
  new Error().stack
}

注意,根据MDN文档,此解决方案已弃用,不应再使用

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/caller


function Hello()
{
    alert("caller is " + Hello.caller);
}

注意,这个特性不是标准的,来自Function.caller:

非标准的 这个特性是非标准的,不在标准轨道上。不要在面向Web的生产站点上使用它:它并不适用于每个用户。实现之间也可能存在很大的不兼容性,将来行为可能会发生变化。


以下是2008年的旧答案,在现代Javascript中不再支持:

function Hello()
{
    alert("caller is " + arguments.callee.caller.toString());
}

只是想让你知道,在PhoneGap/Android上,这个名字似乎不工作。但是arguments.callee.caller.toString()可以做到这一点。