JSLint 声称某些递归函数调用是 "out of scope"

JSLint claims certain recursive function calls are "out of scope"

我有一个带有递归函数调用的 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 中引发任何错误。

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

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

问题似乎是包含赋值的变量声明不会导致 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.

的存在