1

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

我使用谷歌找到的结果是这样的

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

但我想做一些像这样的东西:

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

这可能吗?

4

5 回答 5

5

如果您不在,strict mode您可以使用 获取函数对象arguments.callee,请参阅MDN文档。例如

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

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

(function foo() { 
    foo(); // call to itself
})(); 
于 2012-05-07T15:57:45.737 回答
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)**
于 2012-05-07T16:12:12.490 回答
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 中定义定点组合器的最大缺点是您需要某种惰性求值,以便您的函数不会无限递归。在发布简化版本之前,我必须考虑一下和/或重新阅读这篇文章。当然,我不确定这样的事情会对你有多大帮助,尤其是在性能方面。最容易理解(也许性能更高)的解决方案可能是像其他人建议的那样创建匿名块,正常定义函数并从块中返回它。

于 2012-05-07T16:05:58.860 回答
0

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

setTimeout(function foo() { alert(foo); });
于 2012-05-07T16:05:59.853 回答
0

据我所知,你不能。您必须有一个引用(名称或变量)才能将其回调。

虽有arguments.callee但气馁

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

于 2012-05-07T15:59:48.433 回答