我试图了解为什么我得到以下错误,而不是如何解决它。

将以下代码传递给JSLintJSHint会产生错误'err'已被定义。

/*jslint white: true, devel: true, onevar: true, browser: true, undef: true, nomen: true, regexp: true, plusplus: true, windows: true, bitwise: true, newcap: true, strict: true, maxerr: 50, indent: 4 */
function xyzzy() {

    "use strict";

    try { /*Step 1*/ } catch (err) { }
    try { /*Step 2*/ } catch (err) { }

}

这里明显的假设是catch的行为或应该像函数一样。因此,err既不是xyzzy的全局变量,也不是局部变量,而是catch块的参数。

在浏览ECMA-262 Standard时,描述try语句的12.14节指出catch子句采用绑定(bind)到异常的标识符。另外,catch的语义产生规则是指传递来的参数,该参数将Identifier用作参数。

这似乎向不经意的读者暗示了上面的代码是有效的,并且棉绒工具可能存在错误。

甚至IntelliJ的最严格的JavaScript代码检查分析也没有报告err被重新定义存在问题。

更令人担忧的是,如果这是一个可变的范围界定问题,那么您可能会猜测err正在渗入全局空间,这带来了一系列其他问题,而应该事先声明它,如下所示:
/*jslint white: true, devel: true, onevar: true, browser: true, undef: true, nomen: true, regexp: true, plusplus: true, windows: true, bitwise: true, newcap: true, strict: true, maxerr: 50, indent: 4 */
function xyzzy() {

    "use strict";
    var err;  // DECLARE err SO IT IS CERTAINLY LOCAL

    try { /*Step 1*/ } catch (err) { }
    try { /*Step 2*/ } catch (err) { }

}

但这现在仅在每个catch语句上导致有关err的两个错误,这使问题变得更糟,并可能引入variable shadowing

棉绒工具建议每个catch块不仅引入自己的词法作用域,还引入一个新变量。这是不对的。

简单地使err1err2,...来放置静态分析工具仅能掩盖症状,并且不会有助于编写更干净的代码。

JavaScript专家:这是 Lint 工具中的错误,JavaScript规范的阴暗角还是对这里发生的事情的根本误解?

更新:写给JSLint的作者道格拉斯·克罗克福德(Douglas Crockford),事实证明,出现此警告的理由很充分。请参阅下面的答案。

最佳答案

有关此问题,写给JSLint的作者Douglas Crockford

毕竟有一个很合理的理由...

道格拉斯写道:



如果您查看this similar StackOverflow question,您会注意到PleaseStand开始涉及它。 并非所有浏览器(尤其是历史浏览器)都能正确或一致地处理作用域。

JSLint认识到您的代码可能在一种浏览器中有效,但在另一种浏览器中无效,从而留下了一个非常讨厌和微妙的错误来进行跟踪。该警告是真实的。

通过使用一个不同的名称,是的,它不是干净的或简洁的(因为不是),这恰好是避免遇到问题的通用方法。

谢谢道格拉斯的澄清!谜团已揭开。

关于javascript - JavaScript catch参数已经定义,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6100230/

10-12 07:34
查看更多