Arguments.callee is deprecated - what should be used instead?

For doing things like

setTimeout(function () {
    ...
    setTimeout(arguments.callee, 100);
}, 100);

I need something like arguments.callee. I found information at javascript.info that arguments.callee is deprecated:

This property is deprecated by ECMA-262 in favor of named function expressions and for better performance.

But what should be then used instead? Something like this?

setTimeout(function myhandler() {
    ...
    setTimeout(myhandler, 100);
}, 100);
// has a big advantage that myhandler cannot be seen here!!! 
// so it doesn't spoil namespace

BTW, is arguments.callee cross-browser compatible?

Answers:

Answer

Yes, that's what, theoretically, should be used. You're right. However, it doesn't work in some versions of Internet Explorer, as always. So be careful. You may need to fall back on arguments.callee, or, rather, a simple:

function callback() {
    // ...
    setTimeout(callback, 100);
}

setTimeout(callback, 100);

Which does work on IE.

Answer

minitech answer is quite good, but it is missing one more scenario. Your declare function called callback, which means two things, first the function is object in memory, and the second, the function name is only for referencing to the object. If you, for any reason break the reference between these two, the proposed code will not work too.

Proof:

function callback() {
    // ...
    setTimeout(callback, 100);
}

setTimeout(callback, 100);

var callback2 = callback; //another reference to the same object
callback = null; //break the first reference
callback2(); //callback in setTimeout now is null.

From developer Mozilla page in the description is:

Warning: The 5th edition of ECMAScript (ES5) forbids use of arguments.callee() in strict mode. Avoid using arguments.callee() by either giving function expressions a name or use a function declaration where a function must call itself.

obviously this is the first example of workaround "by either giving function expressions a name", but lets see how we can deal with "or use a function declaration where a function must call itself" and what will that bring:

function callback(){
   //...
   setTimeout(innercall(), 100);
   function innercall(){
      //innercall is safe to use in callback context
      innercall.caller(); //this will call callback();
   }
}

Then we are safe to do whatever we want with the callback reference:

var callback2 = callback;
callback = null;
callback2(); //will work perfectly.
Answer

But what should be then used instead? Something like this?

Yes, you answered your own question. For more information, see here:

Why was the arguments.callee.caller property deprecated in JavaScript?

It has a pretty good discussion about why this change was made.

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.