function main()
{
   Hello();
}

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

有办法找到调用堆栈吗?


当前回答

据我所知,我们有两种方法从给定的资源中得到

arguments.caller whoCalled()函数 { 如果参数。Caller == null) console.log('我是从全局作用域调用的。'); 其他的 console.log(参数。Caller + '打电话给我!'); } Function.caller myFunc()函数 { 如果(myFunc。调用者== null) { 返回'函数是从顶部调用的!'; } 其他的 { 返回'这个函数的调用者是' + myfuncc .caller; } }

我想你已经有答案了:)。

其他回答

注意,根据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());
}

在这里,除了函数名之外的所有内容都被RegExp从caller.toString()中剥离。

<!DOCTYPE html>
<meta charset="UTF-8">
<title>Show the callers name</title><!-- This validates as html5! -->
<script>
main();
function main() { Hello(); }
function Hello(){
  var name = Hello.caller.toString().replace(/\s\([^#]+$|^[^\s]+\s/g,'');
  name = name.replace(/\s/g,'');
  if ( typeof window[name] !== 'function' )
    alert ("sorry, the type of "+name+" is "+ typeof window[name]);
  else
    alert ("The name of the "+typeof window[name]+" that called is "+name);
}
</script>

使用严格模式开/关(JavaScript & TypeScript),如果(!)调用者存在,你可以尝试这个

console.log(`caller:${(new Error()).stack?.split('\n')[2].trim().split(' ')[1]}`)

堆栈跟踪

您可以使用特定于浏览器的代码找到整个堆栈跟踪。好在已经有人成功了;这是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的提示(尽管它们不是跨浏览器的)。

如果你只想要函数名而不是代码,并且想要一个独立于浏览器的解决方案,请使用以下方法:

var callerFunction = arguments.callee.caller.toString().match(/function ([^\(]+)/)[1];

注意,如果数组中没有[1]元素,那么上面的代码将返回错误。要解决这个问题,请使用以下方法:

var callerFunction = (arguments.callee.caller.toString().match(/function ([^\(]+)/) === null) ? 'Document Object Model': arguments.callee.caller.toString().match(/function ([^\(]+)/)[1], arguments.callee.toString().match(/function ([^\(]+)/)[1]);