[javascript] Can I get the name of the currently running function in JavaScript?

Is it possible to do this:

myfile.js:
function foo() {
    alert(<my-function-name>);
    // pops-up "foo"
    // or even better: "myfile.js : foo"
}

I've got the Dojo and jQuery frameworks in my stack, so if either of those make it easier, they're available.

This question is related to javascript jquery dojo-1.6

The answer is


This should do it:

var fn = arguments.callee.toString().match(/function\s+([^\s\(]+)/);
alert(fn[1]);

For the caller, just use caller.toString().


Since you have written a function named foo and you know it is in myfile.js why do you need to get this information dynamically?

That being said you can use arguments.callee.toString() inside the function (this is a string representation of the entire function) and regex out the value of the function name.

Here is a function that will spit out its own name:

function foo() {
    re = /^function\s+([^(]+)/
    alert(re.exec(arguments.callee.toString())[1]);             
}

This a variant of Igor Ostroumov's answer:

If you would like to use it as a default value for a parameter, you need to consider a second level call to 'caller':

function getFunctionsNameThatCalledThisFunction()
{
  return getFunctionsNameThatCalledThisFunction.caller.caller.name;
}

This would dynamically allow for a reusable implementation in multiple functions.

_x000D_
_x000D_
function getFunctionsNameThatCalledThisFunction()_x000D_
{_x000D_
  return getFunctionsNameThatCalledThisFunction.caller.caller.name;_x000D_
}_x000D_
_x000D_
function bar(myFunctionName = getFunctionsNameThatCalledThisFunction())_x000D_
{ _x000D_
  alert(myFunctionName);_x000D_
}_x000D_
_x000D_
// pops-up "foo"_x000D_
function foo()_x000D_
{_x000D_
  bar();_x000D_
}_x000D_
_x000D_
function crow()_x000D_
{_x000D_
  bar();_x000D_
}_x000D_
_x000D_
foo();_x000D_
crow();
_x000D_
_x000D_
_x000D_

If you want the file name too, here is that solution using the answer from F-3000 on another question:

function getCurrentFileName()
{
  let currentFilePath = document.scripts[document.scripts.length-1].src 
  let fileName = currentFilePath.split('/').pop() // formatted to the OP's preference

  return fileName 
}

function bar(fileName = getCurrentFileName(),  myFunctionName = getFunctionsNameThatCalledThisFunction())
{
  alert(fileName + ' : ' + myFunctionName);
}

// or even better: "myfile.js : foo"
function foo()
{
  bar();
}

A combination of the few responses I've seen here. (Tested in FF, Chrome, IE11)

function functionName() 
{
   var myName = functionName.caller.toString();
   myName = myName.substr('function '.length);
   myName = myName.substr(0, myName.indexOf('('));
   return myName;
}

function randomFunction(){
    var proof = "This proves that I found the name '" + functionName() + "'";
    alert(proof);
}

Calling randomFunction() will alert a string that contains the function name.

JS Fiddle Demo: http://jsfiddle.net/mjgqfhbe/


Try:

alert(arguments.callee.toString());

This has to go in the category of "world's ugliest hacks", but here you go.

First up, printing the name of the current function (as in the other answers) seems to have limited use to me, since you kind of already know what the function is!

However, finding out the name of the calling function could be pretty useful for a trace function. This is with a regexp, but using indexOf would be about 3x faster:

function getFunctionName() {
    var re = /function (.*?)\(/
    var s = getFunctionName.caller.toString();
    var m = re.exec( s )
    return m[1];
}

function me() {
    console.log( getFunctionName() );
}

me();

Here is a one liner:

    arguments.callee.toString().split('\n')[0].substr('function '.length).replace(/\(.*/, "").replace('\r', '')

Like this:

    function logChanges() {
      let whoami = arguments.callee.toString().split('\n')[0].substr('function '.length).replace(/\(.*/, "").replace('\r', '');
      console.log(whoami + ': just getting started.');
    }

(function f() {
    console.log(f.name);  //logs f
})();

Typescript variation:

function f1() {} 
function f2(f:Function) {
   console.log(f.name);
}

f2(f1);  //Logs f1

Note only available in ES6/ES2015 compliant engines. For more see


The getMyName function in the snippet below returns the name of the calling function. It's a hack and relies on non-standard feature: Error.prototype.stack. Note that format of the string returned by Error.prototype.stack is implemented differently in different engines, so this probably won't work everywhere:

_x000D_
_x000D_
function getMyName() {_x000D_
  var e = new Error('dummy');_x000D_
  var stack = e.stack_x000D_
                .split('\n')[2]_x000D_
                // " at functionName ( ..." => "functionName"_x000D_
                .replace(/^\s+at\s+(.+?)\s.+/g, '$1' );_x000D_
                return stack_x000D_
}_x000D_
_x000D_
function foo(){_x000D_
  return getMyName()_x000D_
}_x000D_
_x000D_
function bar() {_x000D_
  return foo()_x000D_
}_x000D_
_x000D_
console.log(bar())
_x000D_
_x000D_
_x000D_

About other solutions: arguments.callee is not allowed in strict mode and Function.prototype.calleris non-standard and not allowed in strict mode.


The answer is short: alert(arguments.callee.name);


An updated answer to this can can be found over at this answer: https://stackoverflow.com/a/2161470/632495

and, if you don't feel like clicking:

function test() {
  var z = arguments.callee.name;
  console.log(z);
}

According to MDN

Warning: The 5th edition of ECMAScript (ES5) forbids use of arguments.callee() in strict mode. Avoid using arguments.callee() by either giving function expressions a name or use a function declaration where a function must call itself.

As noted this applies only if your script uses "strict mode". This is mainly for security reasons and sadly currently there's no alternative for this.


The name of the current function and how it can be obtained seems to have changed over the past 10 years, since this question was asked.

Now, not being a pro web developer who knows about all the histories of all browsers ever having existed, here is how it works for me in a 2019 chrome browser:

function callerName() {
    return callerName.caller.name;
}
function foo() {
    let myname = callerName();
    // do something with it...
}

Some of the other answers ran into some chrome errors about strict javascript code and whatnot.


Another use case could be an event dispatcher bound at runtime:

MyClass = function () {
  this.events = {};

  // Fire up an event (most probably from inside an instance method)
  this.OnFirstRun();

  // Fire up other event (most probably from inside an instance method)
  this.OnLastRun();

}

MyClass.prototype.dispatchEvents = function () {
  var EventStack=this.events[GetFunctionName()], i=EventStack.length-1;

  do EventStack[i]();
  while (i--);
}

MyClass.prototype.setEvent = function (event, callback) {
  this.events[event] = [];
  this.events[event].push(callback);
  this["On"+event] = this.dispatchEvents;
}

MyObject = new MyClass();
MyObject.setEvent ("FirstRun", somecallback);
MyObject.setEvent ("FirstRun", someothercallback);
MyObject.setEvent ("LastRun", yetanothercallback);

The advantage here is the dispatcher can be easily reused and doesn't have to receive the dispatch queue as an argument, instead it comes implicit with the invocation name...

In the end, the general case presented here would be "using the function name as an argument so you don't have to pass it explicitly", and that could be useful in many cases, such as the jquery animate() optional callback, or in timeouts/intervals callbacks, (ie you only pass a funcion NAME).


All what you need is simple. Create function:

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

After that whenever you need, you simply use:

function foo() { 
  console.log(getFuncName())
}

foo() 
// Logs: "foo"

For non-anonymous functions

function foo()
{ 
    alert(arguments.callee.name)
}

But in case of an error handler the result would be the name of the error handler function, wouldn't it?


Information is actual on 2016 year.


Results for function declaration

Result in the Opera

>>> (function func11 (){
...     console.log(
...         'Function name:',
...         arguments.callee.toString().match(/function\s+([_\w]+)/)[1])
... })();
... 
... (function func12 (){
...     console.log('Function name:', arguments.callee.name)
... })();
Function name:, func11
Function name:, func12

Result in the Chrome

(function func11 (){
    console.log(
        'Function name:',
        arguments.callee.toString().match(/function\s+([_\w]+)/)[1])
})();

(function func12 (){
    console.log('Function name:', arguments.callee.name)
})();
Function name: func11
Function name: func12

Result in the NodeJS

> (function func11 (){
...     console.log(
.....         'Function name:',
.....         arguments.callee.toString().match(/function\s+([_\w]+)/)[1])
... })();
Function name: func11
undefined
> (function func12 (){
...     console.log('Function name:', arguments.callee.name)
... })();
Function name: func12

Does not work in the Firefox. Untested on the IE and the Edge.


Results for function expressions

Result in the NodeJS

> var func11 = function(){
...     console.log('Function name:', arguments.callee.name)
... }; func11();
Function name: func11

Result in the Chrome

var func11 = function(){
    console.log('Function name:', arguments.callee.name)
}; func11();
Function name: func11

Does not work in the Firefox, Opera. Untested on the IE and the Edge.

Notes:

  1. Anonymous function does not to make sense to check.
  2. Testing environment

~ $ google-chrome --version
Google Chrome 53.0.2785.116           
~ $ opera --version
Opera 12.16 Build 1860 for Linux x86_64.
~ $ firefox --version
Mozilla Firefox 49.0
~ $ node
node    nodejs  
~ $ nodejs --version
v6.8.1
~ $ uname -a
Linux wlysenko-Aspire 3.13.0-37-generic #64-Ubuntu SMP Mon Sep 22 21:28:38 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

Here's a way that will work:

export function getFunctionCallerName (){
  // gets the text between whitespace for second part of stacktrace
  return (new Error()).stack.match(/at (\S+)/g)[1].slice(3);
}

Then in your tests:

import { expect } from 'chai';
import { getFunctionCallerName } from '../../../lib/util/functions';

describe('Testing caller name', () => {

    it('should return the name of the function', () => {
      function getThisName(){
        return getFunctionCallerName();
      }

      const functionName = getThisName();

      expect(functionName).to.equal('getThisName');
    });

  it('should work with an anonymous function', () => {


    const anonymousFn = function (){
      return getFunctionCallerName();
    };

    const functionName = anonymousFn();

    expect(functionName).to.equal('anonymousFn');
  });

  it('should work with an anonymous function', () => {
    const fnName = (function (){
      return getFunctionCallerName();
    })();

    expect(/\/util\/functions\.js/.test(fnName)).to.eql(true);
  });

});

Note that the third test will only work if the test is located in /util/functions