我试图了解为什么我收到以下错误,而不是如何解决该错误。
将以下代码传递给JSLint或JSHint产生错误'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
的参数 block 。
在浏览 ECMA-262 Standard ,第 12.14 节描述了 try
声明表明catch
子句采用绑定(bind)到异常的标识符。另外,catch
的语义产生规则指的是作为参数调用标识符传递的参数。
这似乎向普通读者表明上述代码是有效的,并且 lint 工具可能存在错误。
偶数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) { }
}
但这现在只会导致两个关于 err
的错误在每个 catch 语句中,使问题变得更糟并可能引入 variable shadowing .
lint 工具建议每个 catch
block 不仅引入了它自己的词法范围,还引入了一个新变量。这是不对的。
简单地制作err1
, err2
,...安抚静态分析工具只会隐藏症状,并且不会有助于生成更清晰的代码。
JavaScript 大师:这是 lint 工具中的错误、JavaScript 规范的黑暗 Angular 落,还是对这里发生的事情的根本误解?
更新:写信给 JSLint 的作者 Douglas Crockford,事实证明这个警告有一个非常有效的理由。请参阅下面的答案。
最佳答案
写信给Douglas Crockford JSLint 作者,关于这个问题。
这毕竟是一个非常正当的理由......
道格拉斯写道:
Catch variables are not scoped correctly, so I recommend that you use a different name in each one.
如果你看this similar StackOverflow question你会注意到PleaseStand开始接触它。 并非所有浏览器,尤其是历史悠久的浏览器,都能正确或一致地处理作用域。
JSLint 认识到您的代码可能在一种浏览器中运行,但不能在另一种浏览器中运行,从而留下一个非常令人讨厌且微妙的错误来追踪。 警告是真实的。
通过使用不同的名称,是的,感觉一点也不干净或简洁,因为事实并非如此,这恰好是避免遇到问题的通用方法。
谢谢道格拉斯的澄清!谜团解开了。
关于JavaScript catch 参数已定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6100230/