我有一个带有递归函数调用的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中引发任何错误。
答案 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说它超出范围,声称可能是未定义的那一点。