I need the current function name as a string to log to our log facility. But arguments.callee.name
only works in loose mode. How to get the function name under "use strict"
?

- 32,014
- 33
- 141
- 226
-
2If you are able to modify the function's body to add logging code, can't you just hard-code the function name? What advantage would you have if you could read it from a property? – nnnnnn Jul 18 '16 at 11:36
-
9@nnnnnn someone keeps renaming functions but forgets to update the log line. – exebook Jul 18 '16 at 11:44
-
did you find a nice solution for it? creating an Error object may have a performance impact, so, I'm keep looking the nice way to get the function name. – Kostanos May 11 '22 at 05:14
-
@Kostanos not directly, but a workaround for that particular case what was to type `log('^FUNAME^')` instead and then use my own tiny parser on production that would replace ^FUNAME^ with a current function name which is found after the preceeding word `function`. – exebook May 22 '22 at 16:46
7 Answers
For logging/debugging purposes, you can create a new Error
object in the logger and inspect its .stack
property, e.g.
function logIt(message) {
var stack = new Error().stack,
caller = stack.split('\n')[2].trim();
console.log(caller + ":" + message);
}
function a(b) {
b()
}
a(function xyz() {
logIt('hello');
});

- 211,518
- 52
- 313
- 390
-
-
A great answer @georg. Note that ``[2]`` is relative to this example only, if you have for example a stack containing three parent functions in this case we must change **2** to **3** – ismnoiet Jul 18 '16 at 12:40
-
5@hamism: `stack[2]` is always the function that called the logger, no matter how deep the stack is. – georg Jul 18 '16 at 17:59
-
-
3It is a clever solution for logging/debugging. To anyone else considering using this in production code though (in my case, for event tracking), be warned: *"This feature is non-standard and is not on a standards track. Do not use it on production sites facing the Web: it will not work for every user. There may also be large incompatibilities between implementations and the behavior may change in the future."* (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/Stack) – evanrmurphy Oct 08 '18 at 01:03
You can bind function as its context then you can access its name via this.name
property:
function x(){
console.log(this.name);
}
x.bind(x)();

- 6,424
- 11
- 43
- 76
-
1
-
This is clever, but the effect of bind is permanent, and the value of this cannot be changed again, which can cause bugs. Perharps, x.call(x) might be a better solution – Eazicoding Jul 25 '21 at 16:02
-
@Eazicoding binding does not affect the original function reference. `bind()` creates a copy of the function with the new context. – seebiscuit Jun 27 '23 at 17:49
After little research here is a good solution :
function getFnName(fn) {
var f = typeof fn == 'function';
var s = f && ((fn.name && ['', fn.name]) || fn.toString().match(/function ([^\(]+)/));
return (!f && 'not a function') || (s && s[1] || 'anonymous');
}
function test(){
console.log(getFnName(this));
}
test = test.bind(test);
test(); // 'test'

- 4,129
- 24
- 30
-
6But that doesn't work from within the function unless you already have a reference to the function. OP asked for a replacement for `arguments.callee.name`... – nnnnnn Jul 18 '16 at 11:32
Building on @georg solution, this one returns just the function name. Note though that it may fail if called from an anonymous function
function getFncName() {
const stackLine = (new Error())!.stack!.split('\n')[2].trim()
const fncName = stackLine.match(/at Object.([^ ]+)/)?.[1]
return fncName
}
function Foo() {
console.log(getFncName()) // prints 'Foo'
}

- 1,251
- 11
- 17
A simple solution to dynamically retrieve function names [like magic variables] is the use of scoped variables, and the Function.name property.
{
function foo() {
alert (a.name);
}; let a = foo
}
{
function foo2() {
alert(a.name)
}; let a = foo2
};
foo();//logs foo
foo2();//logs foo2
Note: Nested functions cease to be source elements, and are hence not hoisted. Also, this technique cannot work with anonymous functions.

- 191
- 9
If (like me) you want to define this elsewhere and call it generically, you can store the code as a string somewhere global or import it, then eval()
it wherever to access the current function name. (Using eval keeps the context at the point of invocation.)
There's gotta be a way to do this without using a string, but whatever.
SomeObject.whatFunc =
'const s = new Error().stack;' +
"const stackLine = new Error().stack.split('\\n')[2].trim();" +
'const fncName = stackLine.match(/(?<=at )(.*)(?= \\()/gm)[0];' +
'console.log(fncName);'
// Whereever you want the func name
function countBananas('weeee') {
eval(SomeObject.whatFunc)
// blah blah blah
}
countBananas() // logs 'countBananas'

- 394
- 1
- 4
just an update to get the full name :
function logIt(message) {
var stack = new Error().stack,
// update is on this line
caller = stack.split('\n')[2].trim().split(/\s+/)[1];
console.log(caller.trim().split(/\s+/)[1];);
}
function a(b) {
b()
}
a(function xyz() {
logIt('hello');
});