31

How is it possible to learn the name of function I am in?

The below code alerts 'Object'. But I need to know how to alert "Outer."

function Outer(){

    alert(typeof this);

}
pencilCake
  • 48,449
  • 79
  • 219
  • 356
  • I'm curious, under what circumstances would the name of the function you're in actually not the one written out in the code? – bryantsai Jan 29 '10 at 11:20
  • @bryantsai: `window[window.prompt('Function name:', '')] = function(){ alert(arguments.callee.name); };` – Boldewyn Jan 30 '10 at 13:39
  • Possible duplicate of [Can I get the name of the currently running function in JavaScript?](https://stackoverflow.com/questions/1013239/can-i-get-the-name-of-the-currently-running-function-in-javascript) – Michael Freidgeim May 11 '19 at 22:47

4 Answers4

32

This will work:

function test() {
  var z = arguments.callee.name;
  console.log(z);
}
yannis
  • 670
  • 11
  • 17
24

I think that you can do that :

var name = arguments.callee.toString();

For more information on this, take a look at this article.

function callTaker(a,b,c,d,e){
  // arguments properties
  console.log(arguments);
  console.log(arguments.length);
  console.log(arguments.callee);
  console.log(arguments[1]);
  // Function properties
 console.log(callTaker.length);
  console.log(callTaker.caller);
  console.log(arguments.callee.caller);
  console.log(arguments.callee.caller.caller);
  console.log(callTaker.name);
  console.log(callTaker.constructor);
}

function callMaker(){
  callTaker("foo","bar",this,document);
}

function init(){
  callMaker();
}
marcgg
  • 62,686
  • 49
  • 174
  • 225
  • 3
    unfortunately `arguments.callee` is deprecated, but since ECMA hasn't defined any substitute yet, this is the way to go. – Boldewyn Jan 29 '10 at 11:01
  • @boldewyn: after more searching I saw that too. But while it's deprecated it still works in most browsers. And like you said, there's no alternative sooooo... ^^ – marcgg Jan 29 '10 at 11:05
  • 1
    @Boldewyn, `arguments.callee` is not just deprecated. When strict mode is enabled, accessing it would cause TypeError. – bryantsai Jan 29 '10 at 11:18
  • 4
    I'm not sure arguments.callee is deprecated. Function.arguments and Function.arguments.callee are, but not the callee property of the arguments of a function. From MDC:- JavaScript 1.4: Deprecated callee as a property of Function.arguments, retained it as a property of a function's local arguments variable. – meouw Jan 29 '10 at 11:32
9

As of ES6, you can use Function.prototype.name. This has the added benefit of working with arrow functions, since they do not have their own arguments object.

function logFuncName() {
  console.log(logFuncName.name);
}

const logFuncName2 = () => {
  console.log(logFuncName2.name);
};
jabacchetta
  • 36,224
  • 7
  • 53
  • 71
  • 11
    What about not wanting to use the function's own name? Something like "this.name" where "this" means "this function" rather than "this class"? – Ran Lottem Dec 02 '18 at 08:47
  • 1
    They should have made it like `function.name` or `[this.function].name` – Eagle_ Feb 24 '21 at 21:31
1

Took me a while to figure this out, so tried to make it very clear for rookies like me.

Approach 1 - arguments.callee.name

This approach used to work, but now in ES6 Strict Mode it will fail. Don't use Approach 1.

//approach 1 - don't use
let functionName = arguments.callee.name;
console.log(functionName);

Approach 2 - create a function and use caller.name

This approach works in the latest version of Javascript and will not fail in Strict Mode. Use Approach 2. There are 2 steps.

Step 1 - Create a function that uses caller.name to return the name of the function that called it. Add this function to your code:

function getFuncName() {
   return getFuncName.caller.name
}

Step 2 - Call your function when you need the name of the function your code is currently in.

    function iWantThisName() { 
      console.log(getFuncName())
    }
    
    iWantThisName() 
    // Logs: "iWantThisName"
Joshua Dance
  • 7,242
  • 3
  • 57
  • 62