5

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.

4
  • 1
    Is there a case you can't hardcode the function name? I agree it'd be nice to be able to get it programatically, but is it necessary? Commented Oct 21, 2013 at 18:54
  • Well, yes. I'm trying to create some sort of logging mechanism, and I don't want to have to call the logging mechanism with a set name... I just want it to know the name. It makes more sense doing it this way because it's dynamic. If the function name changes, I might forget to change it for the logger. Commented Oct 21, 2013 at 18:57
  • 2
    It might be easier to look at some of the stack trace visibility mechanisms available in modern browsers. They're not mutually compatible, but it'd probably be cleaner because you wouldn't have to explicitly pass in anything. Commented Oct 21, 2013 at 19:08
  • 1
    Yeah, I saw the whole stack trace approach before posting this question, but it seems like major overkill. I don't understand why something so simple is basically impossible. Commented Oct 21, 2013 at 19:26

2 Answers 2

2

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

Sign up to request clarification or add additional context in comments.

7 Comments

Interesting. I did see that Stack Trace library... it may be my only option at this point. Baffles me that this is so difficult.
That's Javascript for ya! :-)
Poor JavaScript... it's just trying to mature from a kid to an adult, but it's unfortunately stuck in the angsty teenage stage.
@HBP, thanks for the idea, by the way... that's what lead to my answer.
this is definitely the most interesting approach i've seen so far.
|
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.