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'?
}
有办法找到调用堆栈吗?
当前回答
注意,不能使用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
}
*/
}
其他回答
试试下面的代码:
function getStackTrace(){
var f = arguments.callee;
var ret = [];
var item = {};
var iter = 0;
while ( f = f.caller ){
// Initialize
item = {
name: f.name || null,
args: [], // Empty array = no arguments passed
callback: f
};
// Function arguments
if ( f.arguments ){
for ( iter = 0; iter<f.arguments.length; iter++ ){
item.args[iter] = f.arguments[iter];
}
} else {
item.args = null; // null = argument listing not supported
}
ret.push( item );
}
return ret;
}
在火狐21和Chromium-25里为我工作过。
如果你出于某种原因真的需要这个功能,希望它能跨浏览器兼容,不担心严格的东西,并且向前兼容,那么传递一个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;
}
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”的调用者。事实上,它可以在被调用方/调用方方法不起作用的情况下工作。它还会显示上下文,即源文件和行号。然而,要使解决方案跨平台还需要努力。
注意,根据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());
}