Javascript arguments.callee它的用途是什么

Jor*_*.S. 22 javascript anonymous-function

我还没有找到这个变量的任何完整的跨浏览器文档.

什么是arguments.callee?它是如何工作的?

它有哪些论据?

Eli*_*gem 30

arguments.callee是对当前正在调用的函数的引用.首先要做的事情是:不要使用它:如果你处于严格的环境中,它只会出现错误.

但是,亲自 - 而且我并不孤单 - 我会想念这家酒店.在我解释原因之前,我会给你一个伪示例,说明何时使用它:

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

我希望你喜欢闭包,因为我这样做 - 这arguments.callee就是很可能发生的地方.倒数第二行是钱的位置:

(arguments.callee)
Run Code Online (Sandbox Code Playgroud)

是对闭包范围内设置初始超时的匿名函数的引用(在这种情况下可以访问1个DOM元素).匿名函数在返回后是GC,但在这种情况下,我已将它添加到超时回调的作用域(将其作为参数传递给另一个返回实际回调的匿名函数),因此它仍被引用到某处.
现在,如果你是严格的,你不必担心,因为这是代码在严格模式下的样子:

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

命名函数,就是这样.我为什么不喜欢它?arguments.callee引发标志,就像一些封闭技巧正在进行的匿名函数一样.我想这只是一种习惯,但我认为,它可以帮助我更轻松地构建和调试我的代码.
结合IE的病态仇恨,这对任何做客户端脚本的人来说都很自然.不支持严格模式的IE版本往往会将函数名称泄漏到全局名称空间,因此永远不会允许与函数关联的内存(以及我们创建的闭包)进行GC操作.这可能导致循环引用,更糟糕的是,循环DOM引用,这可能导致内存泄漏.

实际上:这是另一个arguments.callee使用where的真实示例:事件委托和分离事件监听器
这里有关于JS严格模式和递归使用的更多信息arguments.callee.

最后一个问题,IMO最明确的示例是如何arguments.callee方便:递归替换功能:

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');
    });
}
Run Code Online (Sandbox Code Playgroud)

正如在MDN上请求的arguments.callee,警告在严格模式下使用(ECMA 5,这解释了为什么DC说arguments.callee已弃用)
以及更严格的


Dan*_*sky 5

它指定当前正在执行的函数,因此arguments.callee是当前函数。如果您需要在匿名函数中递归,这可能会有所帮助。这是来自 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)
Run Code Online (Sandbox Code Playgroud)