已经定义了JavaScript catch参数

Wal*_*ner 20 javascript scope jslint try-catch

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

通过下面的代码来的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) { }

}
Run Code Online (Sandbox Code Playgroud)

这里显而易见的假设是catch行为,或应该表现得像一个函数.因此,err既不是一个全局变量,也不是一个局部变量来xyzzy,而是一个参数catch块.

在浏览ECMA-262标准,12.14节描述try声明表明catch子句接受一个标识符绑定到一个异常.此外语义生产规则catch是指一个参数,则传递呼叫标识符作为参数.

这似乎向随意的读者建议上面的代码是有效的,也许lint工具有一个bug.

即使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) { }

}
Run Code Online (Sandbox Code Playgroud)

但这只会导致err每个catch语句出现两个错误,导致问题变得更糟,并可能引入变量阴影.

lint工具建议每个catch块不仅引入它自己的词法范围,还引入一个新的变量.这不可能是对的.

简单地制作err1,err2......安抚静态分析工具只是隐藏了症状,并没有为更清洁的代码做出贡献.

JavaScript专家:这是lint工具中的一个错误,一个带有JavaScript规范的黑暗角落,还是对这里发生的事情有一个根本的误解?

更新:写给JSLint的作者道格拉斯克罗克福德,结果证明这是一个非常有效的理由.见下面的答案.

Wal*_*ner 10

写信给道格拉斯克罗克福德,JSLint的作者,这个问题.

毕竟,事实证明这是一个非常正确的理由......

道格拉斯写道:

Catch变量的范围不正确,因此我建议您在每个变量中使用不同的名称.

如果你看看这个类似的StackOverflow问题,你会注意到PleaseStand开始触及它. 并非所有浏览器(尤其是历史浏览器)都能正确或一致地处理范围.

JSLint认识到您的代码可以在一个浏览器中工作,但在另一个浏览器中不能工作,留下一个非常讨厌和微妙的错误来追踪. 警告是真实的.

通过使用一个不同的名称,是的,根本不会感觉干净或简洁,因为它不是,恰好是没有遇到问题的普遍方式.

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