How do you find out the caller function in JavaScript?

前端 未结 30 1567
粉色の甜心
粉色の甜心 2020-11-21 17:46
function main()
{
   Hello();
}

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

Is there a way to find out the call

相关标签:
30条回答
  • 2020-11-21 18:05

    heystewart's answer and JiarongWu's answer both mentioned that the Error object has access to the stack.

    Here's an example:

    function main() {
      Hello();
    }
    
    function Hello() {
      var stack = new Error().stack;
      // N.B. stack === "Error\n  at Hello ...\n  at main ... \n...."
      var m = stack.match(/.*?Hello.*?\n(.*?)\n/);
      if (m) {
        var caller_name = m[1];
        console.log("Caller is:", caller_name)
      }
    }
    
    main();

    Different browsers shows the stack in different string formats:

    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)
    

    Most browsers will set the stack with var stack = (new Error()).stack. In Internet Explorer the stack will be undefined - you have to throw a real exception to retrieve the stack.

    Conclusion: It's possible to determine "main" is the caller to "Hello" using the stack in the Error object. In fact it will work in cases where the callee / caller approach doesn't work. It will also show you context, i.e. source file and line number. However effort is required to make the solution cross platform.

    0 讨论(0)
  • 2020-11-21 18:05

    Why all of the solutions above look like a rocket science. Meanwhile, it should not be more complicated than this snippet. All credits to this guy

    How do you find out the caller function in 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)]
    
    0 讨论(0)
  • 2020-11-21 18:06

    It's safer to use *arguments.callee.caller since arguments.caller is deprecated...

    0 讨论(0)
  • 2020-11-21 18:07
    function Hello()
    {
        alert("caller is " + Hello.caller);
    }
    

    Note that this feature is non-standard, from Function.caller:

    Non-standard
    This feature is non-standard and is not on a standards track. Do not use it on production sites facing the Web: it will not work for every user. There may also be large incompatibilities between implementations and the behavior may change in the future.


    The following is the old answer from 2008, which is no longer supported in modern Javascript:

    function Hello()
    {
        alert("caller is " + arguments.callee.caller.toString());
    }
    
    0 讨论(0)
  • 2020-11-21 18:07

    Another way around this problem is to simply pass the name of the calling function as a parameter.

    For example:

    function reformatString(string, callerName) {
    
        if (callerName === "uid") {
            string = string.toUpperCase();
        }
    
        return string;
    }
    

    Now, you could call the function like this:

    function uid(){
        var myString = "apples";
    
        reformatString(myString, function.name);
    }
    

    My example uses a hard coded check of the function name, but you could easily use a switch statement or some other logic to do what you want there.

    0 讨论(0)
  • 2020-11-21 18:08

    Just console log your error stack. You can then know how are you being called

    const hello = () => {
      console.log(new Error('I was called').stack)
    }
    
    const sello = () => {
      hello()
    }
    
    sello()

    0 讨论(0)
提交回复
热议问题