javascript - 递归调用javascript函数

标签 javascript function recursion function-expression

我可以像这样在变量中创建一个递归函数:

/* 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); 行,以便完成所有这些步骤仍然可以得到3 2 1 0 当我们调用 copyFunction(3); 时?我尝试了 this(counter-1); 但这给了我错误 this is not a function

最佳答案

使用命名函数表达式:

您可以为函数表达式指定一个名称,该名称实际上是私有(private)的,并且仅在函数内部可见:

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

这里 myself 仅在函数内部可见

您可以使用这个私有(private)名称递归调用该函数。

参见 13. Function Definition ECMAScript 5 规范:

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 MDN): 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.

关于javascript - 递归调用javascript函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7065120/

相关文章:

javascript - XML 读取代码在我的服务器上工作,但在我的客户端服务器上不工作

ios - 如何将单独函数中生成的随机数同步到另一个@IBAction func

使用 Terraform 和 map 的多个源的 Azure Function AppSettings

java - 将数字从二进制转换为十进制 最高有效位 (MSB) 导致不良结果

PHP - 将字符串递归替换为数字需要很长时间

c# - 合并两个集合,按属性递归组合重复项

javascript - 组件从 v5 或 v4 降级到 angularJS 时出现 Angular 注入(inject)器错误

Javascript框架困惑

javascript 无法在 Internet Explorer 上运行

bash - 检查函数是否定义