6

I'm working on porting some old code to 'strict mode', what are the alternatives to the argument.callee and similar argument.caller etc in the ECMA5 standard?


ADDED INFO: I did not specify why I need the argument.caller/callee.

The code I'm porting is using

assert.ok(elemNode, arguments.callee.name + ": Entity - " + entityId + " has been found");

If it were simple recursion I could use function name(){ ... function() ... }, but I can't seem to find what to do with the above code.

ffledgling
  • 11,502
  • 8
  • 47
  • 69
  • @AlienWebguy Thanks for pointing that out, Added usecase for my problem, the problem I'm trying to solve is not the same as the one solved in that question. – ffledgling Mar 21 '13 at 21:01
  • 1
    Can you include the rest of your unit testing logic? I need more scope to work with here. That one liner isn't giving me any base of reference. thanks. – AlienWebguy Mar 21 '13 at 21:29

4 Answers4

7

Starting with ECMAScript 3, you can have named function expressions. Prior to that function expressions were anonymous, which made arguments.callee necessary. Named function expressions made it unnecessary. So that's the recommended alternative.

See the MDN docs for callee

Example:

[1,2,3,4,5].map(function factorial (n) {
    return !(n > 1) ? 1 : factorial(n-1)*n;
});

The benefits of named functions (from the MDN docs):

  • the function can be called like any other from inside your code
  • it does not pollute the namespace
  • the value of this does not change
  • it's more performant (accessing the arguments object is expensive)
Ben McCormick
  • 25,260
  • 12
  • 52
  • 71
3

Not really.

There is no way to mimic or "polyfill" the arguments.caller property, that has been removed for security reasons, so you can't climb up the scope chain, in-code.

The best alternative for arguments.callee is to just to have named function expressions, instead of anonymous function expressions, like

setTimeout(function loop() {
    if( /* condition */ ) {
        loop();  // instead of arguments.callee();
    }
}, 1000);

That is also faster in almost all implementations (accessing the arguments objects is somewhat slow'ish in general)

jAndy
  • 231,737
  • 57
  • 305
  • 359
1

You need to name your function and then just reference the function by that name.

AlienWebguy
  • 76,997
  • 17
  • 122
  • 145
0

There is no equivalent, strictly speaking. As John Resig points out, you need to name your "anonymous" functions in ECMAScript 5's strict mode and then you can call them directly. His example is:

setTimeout(function later(){
  // do stuff...
  setTimeout( later, 1000 );
}, 1000 );
guypursey
  • 3,114
  • 3
  • 24
  • 42
  • John Resig's blog was the first place I looked for what needed to be done, I looked at Mozilla's developer documentation next, but none of them seem to have an alternative. https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Functions_and_function_scope/Strict_mode – ffledgling Mar 21 '13 at 20:59