1

Is it possible to reference this function's name? For example:

'use strict'
function myClass(){}

myClass.prototype.myName = function myName(data,callback){
    console.log("This function has been called: " + "{???}"); // "myName"
}
myClass.prototype.myAge = function(data,callback){
    console.log("This function has been called: " + "{???}"); // "myAge"
}
var a = new myClass();
a.myName(); // 'myName'
a.myAge();  // 'myAge';

How can I reference "myName" in strict mode like that?

d-_-b
  • 21,536
  • 40
  • 150
  • 256
  • 2
    Are you asking about the `myName` property or the named function? You can clarify by not making the function name and the property names the same – Ruan Mendes Jan 26 '15 at 23:55
  • Any way to dynamically pull the name of the method being executed, so i wouldn't have to hard-code the function name within each `console.log`. – d-_-b Jan 26 '15 at 23:58
  • @d-_-b you can instantiate an `Error` instance and get a stack trace. – Pointy Jan 27 '15 at 00:00
  • Do you want the name of the function or the name of the property the function is assigned to? – Felix Kling Jan 27 '15 at 00:03
  • @FelixKling which is easier? I don't necessarily have to name the functions if I don't need to...? – d-_-b Jan 27 '15 at 00:04
  • 1
    Neither of them actually. Why do you need the name? – Felix Kling Jan 27 '15 at 00:05
  • ...maybe this is an X/Y problem haha... I want to put a console.log every time a function is triggered. I figured this would let me to a generic copy/paste across the board. @FelixKling – d-_-b Jan 27 '15 at 00:06
  • 1
    @d-_-b Neither is possible, you could have two properties pointing to the same function. http://stackoverflow.com/questions/4260308/javascript-getting-the-objects-property-name/4260348#4260348 Also, in strict mode, you do not have access to a function's reference so you cannot know its name even if you gave it a name – Ruan Mendes Jan 27 '15 at 00:07
  • You mean *any* function? That's not possible at runtime. You could do the same thing code coverage tools do and instrument the code before it is executed. But that requires a pre-processing step. – Felix Kling Jan 27 '15 at 00:08

2 Answers2

1

If this is just for debugging, you can use the following, which uses the stack trace to find a function's name, taking advantage of the browser magic that it does to find the "names" of functions. Tested in FF, Chrome and IE 10.

function MyClass() {};

MyClass.prototype.myName = function() {
  console.log(getCallerName(), 'I am here');
};

MyClass.prototype.myOtherName = function() {
  console.log(getCallerName(), 'I am here again');
};


function doMe() {
  console.log(getCallerName(), 'I am here in a named function');
};


function getCallerName() {
  try {
    throw new Error();
  } catch (e) {
    if (e.stack) {
      var lines = e.stack.split('\n');
      // FF (Maybe, Opera and Safari)
      var ffMatch = /\b([a-zA-Z1-9\$_\.]*)@/.exec(lines[1]);
      if (ffMatch) {
        return ffMatch[1];
      }

      // IE 10+ and chrome
      var chromeMatch = /at (.*) /.exec(lines[2]);
      if (chromeMatch) {
        return chromeMatch[1];
      }

    }
    return 'unknown function';
  }
}

var a = new MyClass();

a.myName();
a.myOtherName();
doMe();

Play with it at http://jsfiddle.net/ob0w4z3k/5/

Ruan Mendes
  • 90,375
  • 31
  • 153
  • 217
0

You can use myName.name:

(function myName(){
    console.log("This functions name is " + myName.name);
})(); // "This functions name is myName"

However, note that this was introduced in ECMAScript 6, so most browsers don't support it yet.

Only Firefox has supported it for a long time, because it was a non-standard feature, before ES6 spec was made.

Also see the MDN article.

Oriol
  • 274,082
  • 63
  • 437
  • 513
  • 2
    But this requires knowing the name of the function? If you know the name, why would you use its `.name`? – Ruan Mendes Jan 26 '15 at 23:55
  • @JuanMendes No, it only requires a reference to the function. – Oriol Jan 26 '15 at 23:56
  • 2
    But you are not using a reference to the function, I think the OP would like something that gives you that reference without knowing the name of the function, such as `arguments.callee` but you can't use that because that doesn't work in strict mode. – Ruan Mendes Jan 26 '15 at 23:57
  • 1
    @Oriol I think he means that if you know to type `myName.name` you can just type `"myName"`. – Pointy Jan 26 '15 at 23:59
  • @Pointy Yes, true, if you know the function i called `myName`. But in case you don't know that (e.g if you assign the function to another variable or pass it to another function), you can use `.name`. I think it's not much assuming that, if the OP wants to know the name of a function, he has a reference to the function. – Oriol Jan 27 '15 at 00:04