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'?
}
有办法找到调用堆栈吗?
当前回答
如果你不打算在IE < 11中运行它,那么console.trace()将适合。
function main() {
Hello();
}
function Hello() {
console.trace()
}
main()
// Hello @ VM261:9
// main @ VM261:4
其他回答
看起来这是一个相当解决的问题,但我最近发现,callee是不允许在“严格模式”,所以为了我自己的使用,我写了一个类,将从它被调用的路径。它是一个小型助手库的一部分,如果你想单独使用代码,请更改用于返回调用者堆栈跟踪的偏移量(使用1而不是2)。
function ScriptPath() {
var scriptPath = '';
try {
//Throw an error to generate a stack trace
throw new Error();
}
catch(e) {
//Split the stack trace into each line
var stackLines = e.stack.split('\n');
var callerIndex = 0;
//Now walk though each line until we find a path reference
for(var i in stackLines){
if(!stackLines[i].match(/http[s]?:\/\//)) continue;
//We skipped all the lines with out an http so we now have a script reference
//This one is the class constructor, the next is the getScriptPath() call
//The one after that is the user code requesting the path info (so offset by 2)
callerIndex = Number(i) + 2;
break;
}
//Now parse the string for each section we want to return
pathParts = stackLines[callerIndex].match(/((http[s]?:\/\/.+\/)([^\/]+\.js)):/);
}
this.fullPath = function() {
return pathParts[1];
};
this.path = function() {
return pathParts[2];
};
this.file = function() {
return pathParts[3];
};
this.fileNoExt = function() {
var parts = this.file().split('.');
parts.length = parts.length != 1 ? parts.length - 1 : 1;
return parts.join('.');
};
}
我通常使用(new Error())。堆叠在Chrome。 好处是,这还提供了调用者调用函数的行号。缺点是它将堆栈的长度限制在10,这就是为什么我首先来到这个页面。
(我使用这个在执行期间收集低级构造函数中的调用栈,以便稍后查看和调试,所以设置断点是没有用的,因为它将被命中数千次)
注意,不能使用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 main()
{
Hello();
}
function Hello()
{
new Error().stack
}
概括一下(并说得更清楚)…
这段代码:
function Hello() {
alert("caller is " + arguments.callee.caller.toString());
}
等价于:
function Hello() {
alert("caller is " + Hello.caller.toString());
}
显然,第一部分更容易移植,因为你可以改变函数的名字,从“Hello”说成“Ciao”,但仍然可以让整个程序正常工作。
在后一种情况下,如果你决定重构被调用函数的名称(Hello),你将不得不改变它的所有出现: