6

The alternative to using arguments.callee is to simply name the function, as such:

// Snippet 1, using arguments.callee:
(function(){
    document.body.innerHTML += 'qwe';
    setTimeout(arguments.callee, 1);
})()

// Snippet 2, using naming:
(function f(){
    document.body.innerHTML += 'qwe';
    setTimeout(f, 1);
})()

What is stopping the JavaScript engine/compiler from automatically optimizing Snippet 1 into Snippet 2 above? Is there some inherent limitation existing?

  • MDN's argument basically boils down to:

    ..arguments.callee substantially hinders optimizations like inlining functions, because it must be made possible to provide a reference to the un-inlined function if arguments.callee is accessed.

    However, if we manually name the function and call it via it's name, we are already providing a reference to the function, and thus "hindering optimizations like inlining functions".

  • Olliej's argument is basically "inlining and tail recursion [becomes] impossible in the general case [whereas it is possible if naming is used]". However no evidence is provided and it seems like a handwave (Also see the comments below his post).

Why is function-naming more performant than using arguments.callee?

Community
  • 1
  • 1
Pacerier
  • 86,231
  • 106
  • 366
  • 634
  • 1
    I think the MDN is referring to a named function expression, not an anonymous function expression assigned to a variable (i.e. `(function f(){})`). – Qantas 94 Heavy May 01 '14 at 06:39
  • The first line in ["*Why was arguments.callee removed from ES5 strict mode?*" section of the MDN article](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/arguments/callee#Why_was_arguments.callee_removed_from_ES5_strict_mode.3F) says "*(adapted from [a Stack Overflow answer by olliej](http://stackoverflow.com/a/235760/578288))*" – Bergi May 01 '14 at 10:03

1 Answers1

0

By my reading, MDN is not saying "it's hard to provide a reference to the un-inlined function"; rather, it's saying "it's hard to ensure that, when you access arguments.callee, you get a reference to the un-inlined function".

(This is only half an answer to your question, because it's still not clear to me why arguments.callee should be so much harder to keep up-to-date than the rest of arguments, or than this. So the argument, as it stands, is not obviously compelling. But that's what I think MDN is saying.)

ruakh
  • 175,680
  • 26
  • 273
  • 307
  • But couldn't the compiler ensure that accessing `arguments.callee` would return a reference to the function, since it could (among other alternatives) observe that `arguments` wasn't changed before the call to `arguments.callee`? *Anyway not to be rude, but I think this post is more of a comment...* – Pacerier May 01 '14 at 09:57
  • @Pacerier: I guess that, yes, an intelligent compiler could do that, but it is overly complex (and therefore not done). The comments on olliej's post lead in the same direction. – Bergi May 01 '14 at 10:06
  • @Bergi, Hmm I don't think that's the case (since they often do much more complex stuff)... For this, isn't it simply a matter of setting a flag indicating `arguments.callee` is modified if the body of the function does an assignment to it? The decision to deprecate it in `strict` seems to suggest that there is some hard-wired limitation which couldn't be overcome by future compilers. – Pacerier May 01 '14 at 10:19
  • @Pacerier: Given that the `arguments` object can be saved in a variable, passed to other functions, and so on, I don't think it's all that simple for the interpreter to determine statically whether `arguments.callee` is modified. – ruakh May 02 '14 at 04:49
  • @Pacerier: Also -- I considered posting it as a comment rather than answer. I decided to post it as an answer because its point is that the premise of your question is mistaken. If this is not an answer, then there *is* no answer, and the question should be closed/deleted; but I don't want the question to be closed/deleted, because it's intelligent and valuable, just founded on a minor mistake. – ruakh May 02 '14 at 04:53
  • @ruakh, Ic, but the compiler could easily know whether or not the `arguments` object is assigned to a variable or passed to a function, and only then (since it's more of a special case than the general case to tinkle with the `arguments` object) give it a red flag isn't it? – Pacerier May 02 '14 at 05:00
  • @Pacerier: I believe so, yes. (Or at least, it could rule it out.) – ruakh May 02 '14 at 07:47