7

arguments.callee unfortunatelly deprecated, and using it throws an error in "strict mode".

Is there any new proper(standard) alternative for getting function name inside actual function? Or will it be in future plans ECMA6, 7?

Recent answer is no more than dirty hack and not acceptable for me answer.

And arguments.callee.caller.name not working either (nodejs v7.5.0)

Community
  • 1
  • 1
Firanolfind
  • 1,559
  • 2
  • 17
  • 36
  • 2
    Possible duplicate of [Get current function name in strict mode](http://stackoverflow.com/questions/38435450/get-current-function-name-in-strict-mode) – Jim Deville Feb 26 '17 at 19:55
  • 2
    I already mentioned it. Creating Error object for each calling is just a hack, not a working method. – Firanolfind Feb 26 '17 at 19:57
  • I recommend reading the MDN explanation on [Why was arguments.callee removed from strict mode?](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments/callee#Why_was_arguments.callee_removed_from_ES5_strict_mode) – Matheus Avellar Feb 26 '17 at 19:59
  • 2
    Hack or not, that's still the best I know of. Why do you need the function name? – Jim Deville Feb 26 '17 at 20:01
  • You can see, I provided link to that source. Unfortunately it does not answer my question. – Firanolfind Feb 26 '17 at 20:02
  • It is too complicated to explain it here. For example, I want dynamically wrap method, if it does not have callback in arguments. I have to know method - function's name, before I call it wrapped again. – Firanolfind Feb 26 '17 at 20:05
  • 2
    If you're wrapping a function, couldn't you use `.name` on the function being wrapped? Examples are important. – loganfsmyth Feb 26 '17 at 20:08
  • I agree, but my question is about official alternative for `arguments.callee.name` – Firanolfind Feb 26 '17 at 20:10
  • 2
    Then the answer is there is none, which is why I asked for clarification. You can only get the name of a function you have a reference to, and you cannot get a reference to an arbitrary function in the call stack. If you try to elaborate on the underlying solution you are trying to build, we might be able to give suggestions. – loganfsmyth Feb 26 '17 at 20:13
  • For example `var obj = { method1: function method1(cb){ if(!cb) return this.promise(this.method1); //some async stuff cb(); }, method2: function method2(cb){ if(!cb) return this.promise(this.method2); //some async stuff cb(); }, }` I want to simplify `return this.promise(this.[fn_name])` to `return this.promise(arguments)`. I cannot be done without function name. – Firanolfind Feb 26 '17 at 20:16
  • You can see example of usage in my npm module [wunsch-mixin](https://www.npmjs.com/package/wunsch-mixin) – Firanolfind Feb 26 '17 at 20:22
  • You could use thenify: https://www.npmjs.com/package/thenify to do `var obj = {method1: thenify(function method1(cb){ //some async stuff cb(); }) };` to make `obj.method()` return a promise or take a callback. – loganfsmyth Feb 26 '17 at 20:27
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/136704/discussion-between-loganfsmyth-and-firanolfind). – loganfsmyth Feb 26 '17 at 20:28

2 Answers2

1

Is there any new proper (standard) alternative for getting function name inside actual function?

No, there is not.

Or will it be in future plans for ES?

No, given that there is no need for it. Inside the current function, you know the name and could just as well use a string literal, in other functions you just need some reference (but not .callee).

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • 2
    But is there any way to get **method name**? It is super useful for dynamic methods. – Firanolfind Feb 26 '17 at 21:06
  • @Firanolfind I have no idea what you mean. If it's dynamic, you're already accessing it by name, or no? You might want to post a new question where you can illustrate your [actual problem](http://meta.stackexchange.com/q/66377) with code. – Bergi Feb 26 '17 at 21:12
  • 2
    This is not exactly a "proper" way, so I am not posting it as an answer, bit it might be good enough for debugging. Call `callees()[0]` inside a function to get its name. I only did some basic testing of it: `function callees() { return (new Error()).stack.split(/\n/).slice(2).map(s => s.replace(/^\s+at\s+(\[\w.]+\>?).*/, '$1')) }` – omninonsense May 05 '17 at 10:55
  • There is a need for it( see number of votes in https://stackoverflow.com/questions/1013239/can-i-get-the-name-of-the-currently-running-function-in-javascript and https://stackoverflow.com/questions/2648293/how-to-get-the-function-name-from-within-that-function?noredirect=1&lq=1). “use a string literal” or type name of function inside the function is not DRY – Michael Freidgeim May 12 '19 at 00:16
  • @MichaelFreidgeim What do you mean by "not DRY"? Identifiers are *meant* to be repeated if they refer to the same function/variable/etc. Using `function x() { return x.name; }` is perfectly fine, and every automatic refactoring will take care of all references to `x` when renaming it. – Bergi May 12 '19 at 10:54
  • 2
    If I want to add console.debug(current function name)inside 10 functions , to put actual name within each function is annoying and error prone. Copy and paste console.debug(arguments.callee) is more convenient ( I do not need to repeat function name). Btw, I am using VisualStudio Code and haven’t look at automatic refactoring tools for JavaScript. Can you recommend some? – Michael Freidgeim May 12 '19 at 12:16
  • @MichaelFreidgeim You might want to try `console.trace()` for that purpose. Or just use a debugger/profiler instead of copy-pasting debug statements. – Bergi May 12 '19 at 12:19
  • 1
    Console.trace is too verbose and will produce multiple lines, when I need only function name. Logging and debugging have different use and often logging is more productive over the time (https://stackoverflow.com/questions/618820/logging-vs-debugging/14498099#14498099 ). – Michael Freidgeim May 12 '19 at 13:00
0

If you use Node.js there is a useful package exactly for this problem: caller-id

var callerId = require('caller-id');

function foo() {
    bar();
}

function bar() {
    var callerName = callerId.getData().functionName; /* 'foo' */
}
bugovicsb
  • 422
  • 1
  • 7
  • 15