JSLint 错误:将所有“var”声明移动到函数顶部

Posted

技术标签:

【中文标题】JSLint 错误:将所有“var”声明移动到函数顶部【英文标题】:JSLint error: Move all 'var' declarations to the top of the function 【发布时间】:2011-06-06 11:55:28 【问题描述】:

JSLint 站点已更新,我无法再检查 JS 脚本。对我来说,这个警告并不重要,我不想通过数千行来解决这个问题,我想找到更关键的问题。

有人知道如何关闭此错误,或使用旧版 JSLint 吗?

更新

例子:

function doSomethingWithNodes(nodes)
  this.doSomething();

  for (var i = 0; i < nodes.length; ++i)
    this.doSomethingElse(nodes[i]);
  

  doSomething(); // want to find this problem

jslint.com 输出:

Error:
Problem at line 4 character 8: Move all 'var' declarations to the top of the function.

for (var i = 0; i < nodes.length; ++i)

Problem at line 4 character 8: Stopping, unable to continue. (44% scanned).

问题:

在函数之上具有变量是新要求。我无法使用 JSLINT 来测试代码,因为它会在出现此错误时停止扫描脚本。

我有很多代码,不想将此警告威胁为严重错误。

2011 年 8 月 22 日更新:找到 http://jshint.com,它看起来比 http://jslint.com/ 好很多

【问题讨论】:

你能澄清你的问题吗?你实际上是在问两个问题吗? 如果您取消勾选Stop on first error,它是否仍然会在第一个错误时停止? 这个网站会做得更好 -> glat.info/jscheck @Lee Kowalkowski - 只需将您的代码复制到那里并运行它。我在顶部声明变量,所以它会忽略它们。 (如Window、$等) JSHint 是个不错的选择。 【参考方案1】:

我发现以下语法会消除错误:

function doSomethingWithNodes(nodes) 
    this.doSomething();
    var i; // HERE is where you move the 'var' to the top of the function
    for (i = 0; i < nodes.length; ++i) 
        this.doSomethingElse(nodes[i]);
    

    doSomething(); // want to find this problem

【讨论】:

【参考方案2】:

2017 年 6 月更新:受支持(例如,如果您没有在 Internet Explorer 10 或更低版本中运行 javascript),您应该考虑使用 let 而不是 var。

例如:for(let i=0; ...; i++)


我不可能将var i; 中的for(var i=0; ...; i++) 放在我的函数顶部。特别是当The JavaScript Specification 在for 部分(12.6)中将其作为可接受的语法时。此外,这是Brendan Eich 在他的示例中使用的语法。

将声明移到顶部的想法是,它应该更准确地反映幕后发生的事情,但是,这样做只会反映,不会影响。

对我来说,这是对for 迭代的荒谬期望。更是如此,因为 JSLint 在检测到它时会停止处理。

在函数顶部声明变量是否更具可读性是值得商榷的。我个人更喜欢在使用迭代器变量时声明它们。我不在乎变量是否已经在内部创建,我在这里初始化它,所以我很安全。

我会争辩说,在使用它们的地方声明一个迭代器变量可以确保它们不会意外地变成全局变量(如果你将循环移到另一个函数中,迭代器变量也会随之移动)。这比必须在函数顶部维护变量声明更易于维护。

目前,我使用http://www.javascriptlint.com/online_lint.php,因为它似乎专注于重要的事情。

【讨论】:

另外,请查看 JSHint,它部分是为了响应 JSLint 中的类似内容而创建的。并查看此讨论:***.com/questions/6803305/… 感谢您指向javascriptlint.com/online_lint.php。我一直在使用 JSLint,但是很难理解所有关于错误的毫无意义的胡言乱语,这些错误甚至不是 JSLint 上的错误。 我不同意你的观点,但重要的是要指出 javascript 只有函数作用域。它在 for 循环中没有块范围。因此,即使变量i 定义在for(var i=0; i&lt;10; i+=1) 中,它也可用于整个函数,并在初始化时被提升到顶部。 JSLint 在语法上是正确的,但在这种情况下,按照惯例,没有人以这种方式编码。 NVM 你是完全正确的。我正在测试如果你在函数for(var i=0; i&lt;5; i+=1) 中有两个循环会发生什么,如果编译器会抛出variable already defined 警告,但它没有!即使在严格模式下,重新声明变量也不会引发警告或错误。那么是的,JSLint 是错误的。 @Zon: 或者像任何理智的开发者一样再次使用i。不管你在哪里声明var i,都可以重复使用。【参考方案3】:

尽管 new beta JSLint 没有记录函数内多个 var 容差的注释指令,但它确实 似乎支持来自原版。

原来的JSLint允许你这样做:

/*jslint vars: true */

根据我的经验,这仍然有效——我想是为了向后兼容。撰写本文的时间是 2015 年 6 月。

【讨论】:

【参考方案4】:

Google Closure 编译器实际上将无法正确检测 for...in 循环的循环变量的类型,除非它被声明为 for (var i in ...) 并且似乎没有注释可以解决此问题,因此声明无法移到顶部。

【讨论】:

哦,真的吗?!很遗憾,但分享起来真的很有用,+1。 @jjrv 你有一个不能与闭包编译器一起工作的代码示例吗?我正在使用它,没有发现任何问题。 @JavaKungFu 症状是编译器报告的类型代码少于 100%,如果您在 CompilerOptions.java 中设置 reportUnknownTypes = CheckLevel.WARNING,则会显示警告。 哦好的,我误解了你的回答,我以为它实际上在编译的代码中产生了问题。谢谢。【参考方案5】:

当我们想切换到最新版本的 JSLINT 时,我的代码库出现了这个问题。我们有很多这样的人,人们对移动宣言不满意。我们实际上发现最优雅的解决方案是使用 underscore.js,而不是使用完整的冗长循环,而是使用 _.each() 函数,它消除了 JSLint 错误并使我们的代码更实用、更简洁、更紧凑且更容易阅读。

【讨论】:

【参考方案6】:

您可以随时下载legacy versions,或修改latest version。真的没那么难(搜索move_var)。然后在本地运行 jslint,可以使用节点,也可以使用带有简单 html 表单的浏览器——你可能想要复制 Crockford 的原始版本。

请注意,警告是作为major rewrite 的一部分引入的,并且仅在for( 之后出现,因此该消息有点误导。

【讨论】:

【参考方案7】:

请注意,将所有 var 移到顶部与“允许每个函数使用一个 var 语句”不同。将所有变量移到顶部的要求是新的,似乎没有开关。更多http://groups.google.com/group/jsmentors/browse_thread/thread/5e90c25230f8e22/70e1a95a20fb829e

【讨论】:

以上是关于JSLint 错误:将所有“var”声明移动到函数顶部的主要内容,如果未能解决你的问题,请参考以下文章

JSLint 中迭代器变量的声明被标记为警告

JSLint 错误的解决方案

命名空间模式导致 JSLint '函数在定义之前被使用' 错误

jslint - 不要在循环中创建函数

在 Sublime Text 2 中禁用或覆盖 JSLint 选项

使用胖箭头(放屁)语法定义函数时,vim中的JSlint错误