function main()
{
   Hello();
}

function Hello()
{
  // How do you find out the caller function is 'main'?
}

有办法找到调用堆栈吗?


当前回答

我试图用这个问题来解决这个问题和当前的奖励。

赏金要求在严格模式下获得调用者,我能看到的唯一方法是引用在严格模式外声明的函数。

例如,以下是非标准的,但已经用之前(2016年3月29日)和当前(2018年8月1日)版本的Chrome、Edge和Firefox进行了测试。

函数调用者() { 返回caller.caller.caller; } 使用严格的; main()函数 { //原来的问题: 你好(); //赏金问题: (function() {console.log('匿名函数调用' + caller().name);}) (); } 函数Hello () { //你如何发现调用函数是'main'? console.log('Hello calling by ' + caller().name); } 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 reformatString(string, callerName) {

    if (callerName === "uid") {
        string = string.toUpperCase();
    }

    return string;
}

现在,你可以这样调用这个函数:

function uid(){
    var myString = "apples";

    reformatString(myString, function.name);
}

我的示例使用了对函数名的硬编码检查,但是您可以轻松地使用switch语句或其他逻辑来完成您想要的操作。

只需控制台日志错误堆栈。这样你就可以知道你是如何被召唤的

Const hello = () => { console.log(新的错误('I was called').stack) } Const sello = () => { 你好() } 你可以()

在这里,除了函数名之外的所有内容都被RegExp从caller.toString()中剥离。

<!DOCTYPE html>
<meta charset="UTF-8">
<title>Show the callers name</title><!-- This validates as html5! -->
<script>
main();
function main() { Hello(); }
function Hello(){
  var name = Hello.caller.toString().replace(/\s\([^#]+$|^[^\s]+\s/g,'');
  name = name.replace(/\s/g,'');
  if ( typeof window[name] !== 'function' )
    alert ("sorry, the type of "+name+" is "+ typeof window[name]);
  else
    alert ("The name of the "+typeof window[name]+" that called is "+name);
}
</script>

在ES6和Strict模式下,使用以下方法获取Caller函数

console.log((new Error()).stack.split("\n")[2].trim().split(" ")[1])

请注意,如果没有调用者或没有前一个堆栈,上面的代码行将抛出异常。相应的使用。

获取callee(当前函数名),使用:

console.log((new Error()).stack.split("\n")[1].trim().split(" ")[1])