function main()
{
Hello();
}
function Hello()
{
// How do you find out the caller function is 'main'?
}
有办法找到调用堆栈吗?
function main()
{
Hello();
}
function Hello()
{
// How do you find out the caller function is 'main'?
}
有办法找到调用堆栈吗?
当前回答
使用严格模式开/关(JavaScript & TypeScript),如果(!)调用者存在,你可以尝试这个
console.log(`caller:${(new Error()).stack?.split('\n')[2].trim().split(' ')[1]}`)
其他回答
2018年更新
严格模式下禁止调用。下面是使用(非标准)错误堆栈的替代方案。
下面的函数似乎在Firefox 52和Chrome 61-71中完成了这项工作,尽管它的实现对这两种浏览器的日志格式做了很多假设,应该谨慎使用,因为它会抛出一个异常,并可能在完成之前执行两个正则表达式匹配。
'use strict'; const fnNameMatcher = /([^(]+)@|at ([^(]+) \(/; function fnName(str) { const regexResult = fnNameMatcher.exec(str); return regexResult[1] || regexResult[2]; } function log(...messages) { const logLines = (new Error().stack).split('\n'); const callerName = fnName(logLines[1]); if (callerName !== null) { if (callerName !== 'log') { console.log(callerName, 'called log with:', ...messages); } else { console.log(fnName(logLines[2]), 'called log with:', ...messages); } } else { console.log(...messages); } } function foo() { log('hi', 'there'); } (function main() { foo(); }());
我可以在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"))
如果你出于某种原因真的需要这个功能,希望它能跨浏览器兼容,不担心严格的东西,并且向前兼容,那么传递一个this引用:
function main()
{
Hello(this);
}
function Hello(caller)
{
// caller will be the object that called Hello. boom like that...
// you can add an undefined check code if the function Hello
// will be called without parameters from somewhere else
}
下面是一个函数来获得完整的stacktrace:
function stacktrace() {
var f = stacktrace;
var stack = 'Stack trace:';
while (f) {
stack += '\n' + f.name;
f = f.caller;
}
return 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());
}