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'?
}
有办法找到调用堆栈吗?
当前回答
使用*arguments.callee更安全。调用自参数。不赞成调用…
其他回答
注意,不能使用Function。Node.js中的caller,使用caller-id包代替。例如:
var callerId = require('caller-id');
function foo() {
bar();
}
function bar() {
var caller = callerId.getData();
/*
caller = {
typeName: 'Object',
functionName: 'foo',
filePath: '/path/of/this/file.js',
lineNumber: 5,
topLevelFlag: true,
nativeFlag: false,
evalFlag: false
}
*/
}
注意,根据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”的调用者。事实上,它可以在被调用方/调用方方法不起作用的情况下工作。它还会显示上下文,即源文件和行号。然而,要使解决方案跨平台还需要努力。
只是想让你知道,在PhoneGap/Android上,这个名字似乎不工作。但是arguments.callee.caller.toString()可以做到这一点。
为什么上面所有的解决方案看起来都像火箭科学。同时,它不应该比这段代码更复杂。都要归功于这个家伙
如何在JavaScript中找到调用者函数?
var stackTrace = function() {
var calls = [];
var caller = arguments.callee.caller;
for (var k = 0; k < 10; k++) {
if (caller) {
calls.push(caller);
caller = caller.caller;
}
}
return calls;
};
// when I call this inside specific method I see list of references to source method, obviously, I can add toString() to each call to see only function's content
// [function(), function(data), function(res), function(l), function(a, c), x(a, b, c, d), function(c, e)]