未命名函数JavaScript的递归函数调用

时间:2012-05-07 15:56:25

标签: javascript recursion

我在JavaScript中搜索过Recursive Calls,但我想对“未命名”函数进行递归调用。

我使用Google找到的结果是这样的

function foo() {
   setTimeout("foo()",0);
}

但我想做一些类似的事情:

(function () { alert(this.function) })()

这可能吗?

5 个答案:

答案 0 :(得分:5)

如果您不在strict mode,则可以使用arguments.callee获取功能对象,请参阅MDN文档。 e.g。

(function () { 
    console.log(typeof arguments.callee); // "function"
    arguments.callee(); // call to itself
})(); 

但是正如那里所建议的那样,你应该避免使用这个语句并为函数提供一个标识符,如此

(function foo() { 
    foo(); // call to itself
})(); 

答案 1 :(得分:0)

据我所知,你做不到。你必须有一个引用(名称或变量)来回调它。

虽然有arguments.callee但是不鼓励

  

注意:你应该避免使用arguments.callee()并给每个函数(表达式)命名。

答案 2 :(得分:0)

基本上你正在寻找一种叫做Y-Combinator的东西(或者维基百科把它称为Fixed Point Combinator)。

这篇博文似乎给出了一个很好的介绍(只是撇去它,不确定我能解释一下......)

http://blog.jcoglan.com/2008/01/10/deriving-the-y-combinator/

var Y = function(f) {
  return (function(g) {
    return g(g);
  })(function(h) {
    return function() {
      return f(h(h)).apply(null, arguments);
    };
  });
};
var factorial = Y(function(recurse) {
  return function(x) {
    return x == 0 ? 1 : x * recurse(x-1);
  };
});

factorial(5)  // -> 120

编辑: 我从文章中偷走了这一点,我不得不承认,我发现这真的令人困惑,Y可能会更好地阅读

var Y = function(f) {
    var c1 = function(g) {
        return g(g);
    };
    var c2 = function(h) {
        return function() {
            return f(h(h)).apply(null, arguments);
        };
    }
    return c1(c2);
};

通过观察它,我不确定它是否应该如此简单。在javascript中定义一个fixpoint组合器的最大缺点是你需要某种懒惰的评估,这样你的函数就不会无限递归。在发布简化版本之前,我将不得不考虑它和/或重读文章。当然,我不确定这样的事情对你有多大帮助,尤其是表现明智。最容易理解(也许更高性能)的解决方案可能是像其他人建议的那样创建匿名块,正常定义函数并从块中返回。

答案 3 :(得分:0)

将函数作为值传递时,可以使用函数名称:

setTimeout(function foo() { alert(foo); });

答案 4 :(得分:0)

你永远不应该使用.callee

您只需命名该函数,该函数仅在内部范围内可用

setTimeout(function namedFn(x) { 

  // namedFn() exists in here only (see notes below)
  console.log('hello there ' + x);

  if (!x || x < 10) { 
    namedFn(1 + x || 1);
  } 

}, 5000);

// namedFn() is undefined out here **(except for IE <= 8)**