递归调用一个javascript函数
我可以像这样在一个变量中创建一个递归函数:
/* Count down to 0 recursively.
*/
var functionHolder = function (counter) {
output(counter);
if (counter > 0) {
functionHolder(counter-1);
}
}
有了这个, functionHolder(3);
会输出3
2
1
0
。 假设我做了以下事情:
var copyFunction = functionHolder;
copyFunction(3);
将如上输出3
2
1
0
。 如果我然后改变functionHolder
如下:
functionHolder = function(whatever) {
output("Stop counting!");
然后functionHolder(3);
会给Stop counting!
,如预期。
copyFunction(3);
现在给3
Stop counting!
因为它引用了functionHolder
,而不是函数(它本身指向的)。 在某些情况下这可能是可取的,但是有没有办法编写这个函数,以便它自己调用它自己而不是保存它的变量?
也就是说,是否有可能只改变行functionHolder(counter-1);
所以当我们调用copyFunction(3);
时,经历所有这些步骤仍然会给出3
2
1
0
copyFunction(3);
? 我试过this(counter-1);
但是这给了我错误, this is not a function
。
使用命名函数表达式:
您可以给一个函数表达式一个名称,该名称实际上是私有的 ,并且只能从函数内部看到:
var factorial = function myself (n) {
if (n <= 1) {
return 1;
}
return n * myself(n-1);
}
typeof myself === 'undefined'
这里myself
只在函数本身内部可见 。
您可以使用此专用名称递归调用该函数。
请参阅13. Function Definition
ECMAScript 5规范的13. Function Definition
:
FunctionExpression中的标识符可以从FunctionExpression的FunctionBody中引用,以允许函数以递归方式调用它自己。 但是,与FunctionDeclaration不同,FunctionExpression中的标识符不能被引用,也不会影响包含FunctionExpression的范围。
请注意,Internet Explorer版本8的行为不正确,因为名称实际上在封闭变量环境中可见,并且引用了实际函数的副本(请参阅下面的patrick dw的注释)。
使用arguments.callee:
或者,您可以使用arguments.callee
来引用当前函数:
var factorial = function (n) {
if (n <= 1) {
return 1;
}
return n * arguments.callee(n-1);
}
ECMAScript的第5版禁止在严格模式下使用arguments.callee(),但是:
(来自MDN):在正常代码arguments.callee指的是封闭函数。 这个用例很弱:只需命名封闭函数! 此外,arguments.callee基本上阻碍了内联函数之类的优化,因为如果访问arguments.callee,必须提供对非内联函数的引用。 用于严格模式函数的arguments.callee是一个不可删除的属性,在设置或检索时抛出。
您可以使用arguments.callee
[MDN]访问函数本身:
if (counter>0) {
arguments.callee(counter-1);
}
然而,这将在严格的模式中打破。
我知道这是一个古老的问题,但我想我会提出一个可以使用的解决方案,如果你想避免使用命名函数表达式。 (不是说你应该或不应该避免它们,只是提出另一种解决方案)
var fn = (function() {
var innerFn = function(counter) {
console.log(counter);
if(counter > 0) {
innerFn(counter-1);
}
};
return innerFn;
})();
console.log("running fn");
fn(3);
var copyFn = fn;
console.log("running copyFn");
copyFn(3);
fn = function() { console.log("done"); };
console.log("fn after reassignment");
fn(3);
console.log("copyFn after reassignment of fn");
copyFn(3);
链接地址: http://www.djcxy.com/p/38275.html
上一篇: Calling a javascript function recursively
下一篇: Different font faces and sizes within label text entries in ggplot2