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'?
}
有办法找到调用堆栈吗?
当前回答
我通常使用(new Error())。堆叠在Chrome。 好处是,这还提供了调用者调用函数的行号。缺点是它将堆栈的长度限制在10,这就是为什么我首先来到这个页面。
(我使用这个在执行期间收集低级构造函数中的调用栈,以便稍后查看和调试,所以设置断点是没有用的,因为它将被命中数千次)
其他回答
我认为下面的代码段可能会有帮助:
window.fnPureLog = function(sStatement, anyVariable) {
if (arguments.length < 1) {
throw new Error('Arguments sStatement and anyVariable are expected');
}
if (typeof sStatement !== 'string') {
throw new Error('The type of sStatement is not match, please use string');
}
var oCallStackTrack = new Error();
console.log(oCallStackTrack.stack.replace('Error', 'Call Stack:'), '\n' + sStatement + ':', anyVariable);
}
执行以下代码:
window.fnPureLog = function(sStatement, anyVariable) {
if (arguments.length < 1) {
throw new Error('Arguments sStatement and anyVariable are expected');
}
if (typeof sStatement !== 'string') {
throw new Error('The type of sStatement is not match, please use string');
}
var oCallStackTrack = new Error();
console.log(oCallStackTrack.stack.replace('Error', 'Call Stack:'), '\n' + sStatement + ':', anyVariable);
}
function fnBsnCallStack1() {
fnPureLog('Stock Count', 100)
}
function fnBsnCallStack2() {
fnBsnCallStack1()
}
fnBsnCallStack2();
日志是这样的:
Call Stack:
at window.fnPureLog (<anonymous>:8:27)
at fnBsnCallStack1 (<anonymous>:13:5)
at fnBsnCallStack2 (<anonymous>:17:5)
at <anonymous>:20:1
Stock Count: 100
我会这样做:
function Hello() {
console.trace();
}
注意,根据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());
}
heystewart和JiarongWu的回答都提到了Error对象可以访问堆栈。
这里有一个例子:
函数main() { 你好(); } 函数Hello() { 尝试{ throw new Error(); } catch (err) { Let stack = err.stack; // N.B. stack === "Error\n at Hello…\n at main…\ n……” let m = stack.match(/.*?Hello.*?\n(.*?)\n/); 如果(m) { 让caller_name = m[1]; console.log("Caller is:", caller_name); } } } main ();
不同的浏览器以不同的字符串格式显示堆栈:
Safari : Caller is: main@https://stacksnippets.net/js:14:8
Firefox : Caller is: main@https://stacksnippets.net/js:14:3
Chrome : Caller is: at main (https://stacksnippets.net/js:14:3)
IE Edge : Caller is: at main (https://stacksnippets.net/js:14:3)
IE : Caller is: at main (https://stacksnippets.net/js:14:3)
大多数浏览器会使用var stack = (new Error()).stack来设置堆栈。在Internet Explorer中,堆栈是未定义的——你必须抛出一个真正的异常来检索堆栈。
结论:使用Error对象中的堆栈可以确定“main”是“Hello”的调用者。事实上,它可以在被调用方/调用方方法不起作用的情况下工作。它还会显示上下文,即源文件和行号。然而,要使解决方案跨平台还需要努力。
你可以得到完整的堆栈跟踪:
arguments.callee.caller
arguments.callee.caller.caller
arguments.callee.caller.caller.caller
直到调用者为空。
注意:它会导致递归函数的无限循环。