不推荐使用Arguments.callee - 应该使用什么?

时间:2022-06-25 17:25:36

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:

我需要像arguments.callee这样的东西。我在javascript.info上找到了不推荐使用arguments.callee的信息:

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

ECMA-262不推荐使用此属性,而是使用命名函数表达式以获得更好的性能。

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?

BTW,是arguments.callee跨浏览器兼容吗?

3 个解决方案

#1


10  

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:

是的,理论上应该使用这个。你是对的。但是,它在某些版本的Internet Explorer中不能像往常一样工作。所以要小心。您可能需要依赖arguments.callee,或者更简单地说:

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

setTimeout(callback, 100);

Which does work on IE.

哪个适用于IE。

#2


5  

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?

为什么在JavaScript中不推荐使用arguments.callee.caller属性?

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

它对为什么要做出这种改变进行了很好的讨论。

#3


0  

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.

minitech的答案相当不错,但又缺少一个场景。你的声明函数叫做回调,这意味着两件事,首先是函数是内存中的对象,第二,函数名只是用于引用对象。如果您出于任何原因打破了这两者之间的引用,那么建议的代码也不会起作用。

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:

来自开发人员Mozilla页面的描述是:

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.

警告:第5版ECMAScript(ES5)禁止在严格模式下使用arguments.callee()。避免使用arguments.callee()通过为函数表达式赋予名称或使用函数必须调用自身的函数声明。

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.

#1


10  

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:

是的,理论上应该使用这个。你是对的。但是,它在某些版本的Internet Explorer中不能像往常一样工作。所以要小心。您可能需要依赖arguments.callee,或者更简单地说:

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

setTimeout(callback, 100);

Which does work on IE.

哪个适用于IE。

#2


5  

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?

为什么在JavaScript中不推荐使用arguments.callee.caller属性?

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

它对为什么要做出这种改变进行了很好的讨论。

#3


0  

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.

minitech的答案相当不错,但又缺少一个场景。你的声明函数叫做回调,这意味着两件事,首先是函数是内存中的对象,第二,函数名只是用于引用对象。如果您出于任何原因打破了这两者之间的引用,那么建议的代码也不会起作用。

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:

来自开发人员Mozilla页面的描述是:

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.

警告:第5版ECMAScript(ES5)禁止在严格模式下使用arguments.callee()。避免使用arguments.callee()通过为函数表达式赋予名称或使用函数必须调用自身的函数声明。

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.