简体   繁体   中英

JavaScript: Get function name inside of itself

Yes, I realize there are countless threads out there about this issue, for starters:

Get function name from function itself [duplicate]

Get function name from inside itself

Arguments.callee is deprecated - what should be used instead?

But the problem with the answers given is arguments.callee is deprecated . All of the answers say to just give your function a name. However, from what I can tell, that does not fix my problem. Say I have the following function:

function blah() {
  // arguments.callee.name is deprecated
  console.log('The function name is: ' + arguments.callee.name + '.');
}

But because that's deprecated, I shouldn't be using it, so what should I be using instead? Is there any way I can access the function name when inside the function itself, or am I just out of probability here?

If it makes things easier, I am using the framework Ext JS, but I haven't found a way of knowing the function's name. If not, is there a jQuery approach? I'm desperate here.

You can provoke an exception and examine the stack trace.

The following proof of context works in the Chrome browser:

function test () {
  try { [].undef () } catch (e) {
     console.log (e.stack.split ('\n')[1].split (/\s+/)[2]);
  }
}

For a more robust implementation consult http://www.eriwen.com/javascript/js-stack-trace/ which provides a full stack trace in any browser.

A more modern and comprehensive stack trace analyzer is http://stacktracejs.com

With some poking around, I came up with this SO thread , so building on top of that, I made a very very hacky solution that works (in both Chrome and FF... not sure about IE, but I doubt it works). Warning : this is very specific to my own use, so your mileage will definitely vary. Anyway, this is my code:

getLogLocation: function() {
  var ua = navigator.userAgent;
  var isFF = ua.search(/firefox/i) !== -1 ? true : false;
  var isChrome = ua.search(/chrome/i) !== -1 ? true : false;
  if (isFF || isChrome) {
    var stack = Error().stack,
        cname = '',
        funcPattern,
        classPattern = /.*\/(.*)\.js/;  // looking for something between the last backslash and .js
    if (stack) {
      var stacks = stack.split('\n');
      if (stacks) {
        var theStack;
        // the browsers create the stack string differently
        if (isChrome) {
          // the stack has getClassName, then logMessage, then our calling class, but Chrome has some added garbage
          theStack = stacks[4];
          funcPattern = /.*\.(.*)\s+\(/;   // looking for something between a period and the first paren
        }
        else {
          theStack = stacks[2];
          funcPattern = /^\.*(.*)\@/;  // looking for something between a period and an @ symbol
        }
        var matches = theStack.match(classPattern);
        cname = matches[1] + '::';
        matches = theStack.match(funcPattern);
        cname += matches[1] + ':';
      }
    }
    return cname;
  }
}

And if you're curious what my stack looks like, here're the relevant lines:

Firefox (cut out a lot of lines)

".getClassName@http://127.0.0.1/javascripts/app/mixins/ConsoleMixin.js?_dc=1383836090216:72
.logMessage@http://127.0.0.1/javascripts/app/mixins/ConsoleMixin.js?_dc=1383836090216:31
.constructor@http://127.0.0.1/javascripts/app/BaseController.js?_dc=1383836089659:39
..."

Chrome (the first 2 lines are the garbage I have to accommodate for... after that, it's similar to FF's Stack string)

"Error
    at Error (<anonymous>)
    at Ext.define.getLogLocation (http://127.0.0.1/javascripts/app/mixins/ConsoleMixin.js?_dc=1383836606405:72:19)
    at Ext.define.logMessage (http://127.0.0.1/javascripts/app/mixins/ConsoleMixin.js?_dc=1383836606405:31:24)
    at new Ext.define.constructor (http://127.0.0.1/javascripts/app/BaseController.js?_dc=1383836606265:39:14)
    ..."

See this jsFiddle for a working example... had to change the stack values because we're no longer in Ext JS.

Now, a little explanation. getLogLocation resides as a function in an Ext JS class ( ConsoleMixin ), and another function inside of ConsoleMixin ( logMessage ) calls getLogLocation, and logMessage is called by our outer class's function ( constructor ), which is why I have to compensate for the first 2 stack values. Like I said, very hacky and specific to my need, but hopefully someone can make use of it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM