我在JavaScript中搜索过Recursive Calls,但我想对“未命名”函数进行递归调用。
我使用Google找到的结果是这样的
function foo() {
setTimeout("foo()",0);
}
但我想做一些类似的事情:
(function () { alert(this.function) })()
这可能吗?
答案 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)
答案 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)**