Javascript arguments.callee what is it for

30,258

Solution 1

arguments.callee is a reference to the function that is currently being called. First things first: don't use it: if you're in a strict context, it'll just spew errors.

However, personally -and I'm not alone in this- I'll miss this property. Before I get to explain why, I'll give you a pseudo-example of when you might use this:

var looper = (function(someClosureVar)
{
    setTimeout((function(resetTimeout)
    {
        return function()
        {
            //do stuff, stop OR:
            resetTimeout();
        };
    }(arguments.callee)),1000);
}(document.getElementById('foobar')));

I hope you like closures, because I do - and that's where arguments.callee are very likely to occur. The next-to-last line is where the money is:

(arguments.callee)

Is a reference to the anonymous function that sets the initial timeout, within a closure scope (that has access to 1 DOM element, in this case). Anonymous functions are GC'ed after they return, but in this case, I've added it to the timeout callback's scope (passed it as an argument to another anonymous function that returns the actual callback), so it is still referenced somewhere.
Now, if you're in strict you needn't worry because this is what the code would look like in strict mode:

var looper = (function tempName(someClosureVar)
{
    setTimeout((function(resetTimeout)
    {
        return function()
        {
            //do stuff, stop OR:
            resetTimeout();
        };
    }(tempName)),1000);
}(document.getElementById('foobar')));

Name the function and that's it. Why don't I like it? arguments.callee raises flags, just like anonymous functions that some closure trickery is going on. I guess it's just a habit, but its one that, I feel, helps me to structure and debug my code more easily.
Couple that with a pathological hatred for IE, which comes natural to anyone doing some client-side scripting. IE versions that don't support strict mode, tend to leak the function name to the global namespace, thus never allowing the memory associated with the function (and the closure we've created) to be GC'ed. Which might lead to circular references, and, worse still, circular DOM references, which can lead to memory-leaks.

Actually: here's another, real example of where arguments.callee is used: event delegation and detaching event listeners
here's some more info on JS strict mode and recursion using arguments.callee.

The last question has, IMO the most clear cut example of how arguments.callee is handy: recursive replacing functions:

function someF(foo)
{
    //'use strict'; <-- would throw errors here
    foo = foo.replace(/(a|b)+/gi, function (p1,p2)
    {
        if (p1.match(/(a|b){2,}/i))
        {
            return p1.replace(/(a|b)/gi,arguments.callee);//recursive
        }
        return (p2.match(/a/i) ? 'X':'Y');
    });
}

As requested arguments.callee on MDN, warns for usage in strict mode (ECMA 5, that explains why DC says arguments.callee is deprecated)
And more on strict

Solution 2

It specifies the currently executing function, so arguments.callee is the current function. It may be helpfull if you need to go recursive in anonimous function. Here example from mozilla:

function create() {
   return function(n) {
      if (n <= 1)
         return 1;
      return n * arguments.callee(n - 1);
   };
}

var result = create()(5); // returns 120 (5 * 4 * 3 * 2 * 1)

Solution 3

Calee is part of the ECMAScript 3 standard, so it should be safe for cross-browser use. Callee holds the function that is currently executing and invoking it will invoke the current function. Therefore callee takes exactly the same arguments as the enclosing function (or rather it is the current function). Some more information is available here: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Functions_and_function_scope/arguments/callee

It is considered bad style to use callee. Give you function a name instead and use this name...

Solution 4

arguments.callee is a round about way of knowing the current executing function by asking 'Who is calling this specific argument?' . . . .

 function factorial(a){
    if(a>0)
      return a*arguments.callee(a-1);
 }

Here if you call factorial(5), it will check for condition greater than 0, and if it is true, will execute the same logic for the next lesser number . . . In some cases you don't know the name of the function to be called . . . .so you can use this property

here is a good reference

arguments.callee from MDN

UPDATE: arguments.callee() is deprecated in ES5

Solution 5

callee is a property of the arguments object. It can be used to refer to the currently executing function inside the function body of that function.

MDN docs here

Share:
30,258
Jordi P.S.
Author by

Jordi P.S.

Updated on April 29, 2020

Comments

  • Jordi P.S.
    Jordi P.S. about 4 years

    I haven't found any complete cross-browser doc of this variable.

    What is arguments.callee for? how does it work?

    Which arguments does it have?