64

Sorry for the really weird title, but here’s what I’m trying to do:

var f1 = function (param1, param2) {

    // Is there a way to get an object that is ‘f1’
    // (the current function)?

};

As you can see, I would like to access the current function from within an anonymous function.

Is this possible?

gustavohenke
  • 40,997
  • 14
  • 121
  • 129
Nathan Osman
  • 71,149
  • 71
  • 256
  • 361

4 Answers4

63

Name it.

var f1 = function fOne() {
    console.log(fOne); //fOne is reference to this function
}
console.log(fOne); //undefined - this is good, fOne does not pollute global context
amik
  • 5,613
  • 3
  • 37
  • 62
  • 4
    I wonder who downvoted this. This is basically how one accesses current function in anonymous function. And the name is preserved even if it is then assigned to another object, so recursion is still possible. – Markos Oct 15 '15 at 06:34
  • 6
    @Markos—a function expression with a name is not "anonymous" any more. ;-) – RobG Feb 23 '16 at 00:42
  • 1
    @RobG It's just terminology. Since the name on function expression serves only for the code within the function, it is *basically* anonymous from the outside point of view. The only place where name is visible from the outside is function statement. – Markos Feb 23 '16 at 11:17
  • 1
    I wasn't sure when I first started learning JavaScript, but know I know that this is *the* correct answer. – wizzwizz4 Jul 05 '16 at 16:08
  • 1
    This answer assumes that you know which function you are in - in which case it is indeed trivial. However, usually the requirement is to find out which function you are in at runtime, for debugging, stack tracing, etc. purposes, and this naming approach is useless. – Mr. TA Jun 03 '17 at 20:45
  • This is a good, simple solution. Now that things like `arguments.callee()` have been deprecated, it is the only reliable way to reference the function. I might add that the actual name of the function function is irrelevant, so it’s cheap to get into the habit of always naming anonymous functions with a standard name, such as `fn`. Perhaps it would have been nice for JavaScript to have a pseudo-variable for this purpose, similar to `this` for objects. And I agree, using this name doesn’t mean that the function is no longer anonymous. – Manngo Jul 08 '18 at 01:01
41

Yes – arguments.callee is the current function.

NOTE: This is deprecated in ECMAScript 5, and may cause a performance hit for tail-call recursion and the like. However, it does work in most major browsers.

In your case, f1 will also work.

Rory O'Kane
  • 29,210
  • 11
  • 96
  • 131
Christian Mann
  • 8,030
  • 5
  • 41
  • 51
  • 5
    `arguments.callee` is not the right tool for this situation. It is deprecated in ECMAScript 5 "strict mode", and prevents certain optimisations by minifiers. – David Tang Jan 11 '11 at 05:21
  • 23
    @Box9 is there an alternative? – Dirk Boer Nov 18 '14 at 09:04
  • 6
    @DavidTang it may be deprecated, but it is the only option available. Perhaps they should un-deprecate it. – Mr. TA Jun 03 '17 at 20:42
  • 2
    Do note that this does not work when using the 'strict mode'. – Alex Aug 16 '17 at 20:45
  • 5
    arguments.callee is very useful when you're doing a lot of cut and paste work across a lot of functions where naming the function would require significant manual updating. It's also safer if you ever refactor code as the risk of you now referencing the wrong function is very much reduced. – jmc Jan 21 '18 at 09:04
  • @jmc Exactly, it's like a static variable for a function. You can use it for `XMLHttpRequest`s and keep all your code in a single function, instead of scattering it around a bunch of callbacks and whatnot. –  Feb 07 '19 at 20:11
  • Probably worth editing to note that this is no longer "current", given that ES5 has come and gone by now. – Mike 'Pomax' Kamermans Jan 17 '20 at 19:48
14

You can access it with f1 since the function will have been assigned to the variable f1 before it is called:

var f1 = function () {
    f1(); // Is valid
};

f1(); // The function is called at a later stage
David Tang
  • 92,262
  • 30
  • 167
  • 149
  • 1
    ...which is weird, but useful. Not quite an appropriate answer to the (ambiguously exampled) question, though, as George wanted to recurse in an *anonymous* function. – Christian Mann Jan 11 '11 at 05:21
  • 3
    @Christian, it is not weird at all. Function declaration and function execution are two entirely different things. And I believe this *is* the more correct solution to the OP's question - `var f1 = function () {}` is an anonymous function. `function f1() {}` is not. Please see http://stackoverflow.com/questions/103598/why-was-the-arguments-callee-caller-property-deprecated-in-javascript for why `arguments.callee` should be avoided. – David Tang Jan 11 '11 at 05:24
  • 1
    Ah, I see. Weird because the `Function` object was not fully constructed at the time of definition, therefore (in my mind) not assigned to `f1`. I thought that George was wanting to recurse in an anonymous function, say, in a JQuery event handler or something. – Christian Mann Jan 11 '11 at 05:27
  • @ChristianMann it makes sense as the reference is used just when the function is called, not defined. this will work too: var x = function() {console.log(y);}; var y = 'test'; – amik Aug 03 '15 at 20:16
  • Those will work but for a different reason – when the function will be called has nothing to do with it. JavaScript has a lexical scope, so all the references that are closed over, will be solidified at the definition site! The real reason why it works is that the variable definitions are function-wide, defining stuff later is just a syntactic sugar. So the referees exist already when the closure is created. – GolDDranks Sep 05 '17 at 12:43
0

From what I read, arguments.callee is not deprecated; What’s deprecated is the Function.prototype.arguments property.

The arguments property of Function objects is deprecated. The recommended way to access the arguments object is to refer to the variable arguments available within functions.

Nonetheless:

Accessing arguments.callee in strict mode will throw a TypeError.

  • I am sorry, but it's marked deprecated: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments/callee (from the same second reference you mentioned). – Artfaith Jun 23 '23 at 11:57