42

I want to do the opposite of Get JavaScript function-object from its name as a string?

That is, given:

function foo()
{}
function bar(callback)
{
 var name = ???; // how to get "foo" from callback?
}
bar(foo);

How do I get the name of the function behind a reference?

asked May 16, 2012 at 17:59
4
  • var bat = foo; bar(bat) - now what should it print? Commented May 16, 2012 at 18:03
  • 2
    @Alnitak. It should print foo. that's the function name. bat is a variable with a reference to the foo function. Commented May 16, 2012 at 18:06
  • 1
    what happens if the callback doesn't have a name? -- ie bar(function() {...}); Commented May 16, 2012 at 21:21
  • 1
    @Spudley: ideally, the code should throw an exception stating that anonymous functions are not supported. Commented May 17, 2012 at 1:03

9 Answers 9

31

If you can't use myFunction.name then you can:

// Add a new method available on all function values
Function.prototype.getName = function(){
 // Find zero or more non-paren chars after the function start
 return /function ([^(]*)/.exec( this+"" )[1];
};

Or for modern browsers that don't support the name property (do they exist?) add it directly:

if (Function.prototype.name === undefined){
 // Add a custom property to all function values
 // that actually invokes a method to get the value
 Object.defineProperty(Function.prototype,'name',{
 get:function(){
 return /function ([^(]*)/.exec( this+"" )[1];
 }
 });
}
Gili
90.9k109 gold badges419 silver badges732 bronze badges
answered May 16, 2012 at 18:03
Sign up to request clarification or add additional context in comments.

5 Comments

Ohhh, now I got it, the ( if for the exec match, not a part of the regex. cool. +1. BTW, why it doesn't alert foo)?
Why it doesn't match foo){...?
@gdoron Because regex must match characters sequentially until it stops. The function in the regex starts it matching, and then it consumes zero or more anything-but-a-( characters (as many as possible). Once it has done that, it must stop; it can't "skip over" non-matches and continue on.
This relies on this referring to the function object. That's not always the case though! foo.bar() -> this === foo for example.
modified a bit not to include spaces: /function ([^(\s]*)/
24
var name = callback.name;

MDN:

The name property returns the name of a function, or an empty string for anonymous functions:

Live DEMO

answered May 16, 2012 at 18:01

1 Comment

[the name] property is not standard is no longer true, it's in ECMA 6.0 / 2015: ecma-international.org/ecma-262/6.0/#sec-setfunctionname / Also see 2ality.com/2015/09/function-names-es6.html
6
function bar(callback){
 var name=callback.toString();
 var reg=/function ([^\(]*)/;
 return reg.exec(name)[1];
}
>>> function foo() { };
>>> bar(foo);
"foo"
>>> bar(function(){});
""
answered May 16, 2012 at 18:09

3 Comments

More elegant regex than mine; nice :) Are you certain that all browsers will place a space after the leading function?
@Phrogz I'm confident enough not to change the above. If there is an edge case, it would only affect the anonymous function anyway, and bar could easily be adjusted to take that into account.
Having seen your code I recall looking at the spec long ago for the normalized string representation and IIRC the space is required.
2
var x = function fooBar(){};
console.log(x.name);
// "fooBar"
answered May 16, 2012 at 18:02

Comments

1

try to access the .name property:

callback.name 
JMax
26.7k12 gold badges74 silver badges89 bronze badges
answered May 16, 2012 at 18:03

Comments

1

You can extract the object and function name with:

function getFunctionName()
{
 return (new Error()).stack.split('\n')[2].split(' ')[5];
}

For example:

function MyObject()
{
}
MyObject.prototype.hi = function hi()
{
 console.log(getFunctionName());
};
var myObject = new MyObject();
myObject.hi(); // outputs "MyObject.hi"
answered Oct 30, 2014 at 12:17

3 Comments

This will probably work, but isn't it much more expensive to construct a stack-trace than to parse this.toString()?
Yeah, but I'm only using this for debug messages. The above answers would only return "hi" this returns "MyObject.hi".
That is really nice for debugging. Thanks or sharing!
0

If you were looking for the function on an specific object event, this may help:

var a = document.form1
a.onsubmit.name
answered Apr 22, 2013 at 14:32

Comments

0

for me, with just a little modification (adding \ before parent), this work:

if (Function.prototype.name === undefined){
 // Add a custom property to all function values
 // that actually invokes a method to get the value
 Object.defineProperty(Function.prototype,'name',{
 get:function(){
 return /function ([^\(]*)/.exec( this+"" )[1];
 }
 });
}
answered Nov 24, 2014 at 9:12

Comments

-1

I think the answer is simpler than most of these. If the function is

function func() {}

then the name of the function as a string is func.toString() .

If the function is unnamed, then you would have to find the name of the variable or constant that stores its name (which depends on the program code).

answered Sep 1, 2024 at 14:12

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.