递归调用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);将给予停止计数!,如预期。

copyFunction(3);现在给3停止计数!因为它指的是functionHolder,而不是函数(它本身指向的)。这在某些情况下可能是可取的,但是有一种方法来写函数,使它调用自身而不是保存它的变量?

也就是说,是否可以只改变行functionHolder(counter-1);所以经过所有这些步骤仍然给出3 2 1 0当我们调用copyFunction(3);?我试过这个(counter-1);但是给我错误这不是一个函数。

使用命名函数表达式:

你可以给一个函数表达式一个实际上是私有的名称,并且只能从函数ifself内部看到:

var factorial = function myself (n) {
    if (n <= 1) {
        return 1;
    }
    return n * myself(n-1);
}
typeof myself === 'undefined'

这里我自己只在函数本身内部可见。

您可以使用此专用名称来递归调用函数。

参见ECMAScript 5规范的13. Function Definition

The Identifier in a FunctionExpression can be referenced from inside the FunctionExpression’s FunctionBody to allow the function to call itself recursively. However, unlike in a FunctionDeclaration, the Identifier in a FunctionExpression cannot be referenced from and does not affect the scope enclosing the FunctionExpression.

请注意,高达版本8的Internet Explorer的行为不正确,因为该名称实际上在封闭变量环境中可见,并且它引用了实际函数的副本(请参见下面的patrick dw的注释)。

使用arguments.callee:

或者,您可以使用arguments.callee来引用当前函数:

var factorial = function (n) {
    if (n <= 1) {
        return 1;
    }
    return n * arguments.callee(n-1);
}

ECMAScript的第5版在strict mode中禁止使用arguments.callee(),但是:

(From 07003): In normal code arguments.callee refers to the enclosing function. This use case is weak: simply name the enclosing function! Moreover, arguments.callee substantially hinders optimizations like inlining functions, because it must be made possible to provide a reference to the un-inlined function if arguments.callee is accessed. arguments.callee for strict mode functions is a non-deletable property which throws when set or retrieved.

http://stackoverflow.com/questions/7065120/calling-a-javascript-function-recursively

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:递归调用JavaScript函数