JSLint声称某些递归函数调用“超出范围”

时间:2015-11-18 18:22:29

标签: javascript recursion jslint

我有一个带有递归函数调用的JavaScript snippet

(function () {
    "use strict";

    var recurse = function (x) {
        if (x <= 0) {
            return;
        }
        return recurse(x - 1);
    };

    recurse(3);
}());

除了召唤自己几次之外什么都不做,但它会运行。

将上述内容粘贴到JSLint会给我这个错误:

'recurse' is out of scope.

但是,如果我粘贴以下代码段(使用函数声明而不是var):

(function () {
    "use strict";

    function recurse(x) {
        if (x <= 0) {
            return;
        }
        return recurse(x - 1);
    }

    recurse(3);
}());

JSLint喜欢它,没有错误。

我知道JSLint的目标是防止JavaScript代码中的错误。有谁知道为什么JSLint认为第一个是糟糕的JavaScript?通过不以第一种方式进行递归调用,我阻止了什么错误?

编辑:此问题的任何未来访问者:这些JavaScript代码段都不会在最新版本的JSLint中引发任何错误。

2 个答案:

答案 0 :(得分:4)

这两种风格都没有错。据我所知,这是一个不恰当的警告。

问题似乎是包含赋值的变量声明不会导致JSLint在范围内注册声明的变量名称,直到评估整个赋值。也就是说,当JSLint读取var recurse = ...时,它不会意识到recurse是一个声明的变量,直到它评估赋值的右侧。在这种情况下,右侧包含一个使用声明的变量recurse的函数,但JSLint还不知道recurse的存在,因为它还没有完成解析整个任务。

请注意,此代码与您的var示例完全相同但在JSLint中生成无警告

(function () {
    "use strict";

    var recurse;
    recurse = function (x) {
        if (x <= 0) {
            return;
        }
        return recurse(x - 1);
    };

    recurse(3);
}());

通过将var recurse作为单独的语句绘制出来,JSLint首先获知在当前作用域中声明了recurse,然后然后解析了作业。使用组合var recurse = ...(再次,没有错),JSLint首先错误地解析赋值,然后了解recurse的存在。

答案 1 :(得分:0)

当你定义函数时,变量recurse还没有定义,这就是为什么JSLint说它超出范围,声称可能是未定义的那一点。