JavaScript catch参数已定义。

我试图了解为什么我得到以下错误,而不是解决方法。 将以下代码传递给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
块的参数。 在浏览ECMA-262标准时,描述“ 5”语句的12.14节指示“ 1”子句采用绑定到异常的标识符。另外,“ 1”的语义产生规则指的是传递来的参数,该参数将标识符称为参数。 对于临时读者来说,这似乎暗示上述代码是有效的,并且棉绒工具可能存在错误。 甚至IntelliJ最严格的JavaScript代码检查分析也没有报告重新定义ѭ2的问题。 更令人担忧的是,如果这是一个可变的范围界定问题,那么人们可能会猜测ѭ2正在渗入全球空间,这带来了一系列其他问题,而应该事先声明它,例如:
/*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
的两个错误,这使问题变得更糟,并可能引入可变阴影。 棉绒工具建议每个ѭ1块不仅引入其自身的词法范围,还引入一个新变量。这是不对的。 简单地使用
err1
err2
...来放置静态分析工具仅能掩盖症状,并且不会有助于编写更清晰的代码。 JavaScript Gurus:这是皮棉工具中的错误,JavaScript规范的阴暗角还是对这里发生的事情的根本误解? 更新:写给JSLint的作者道格拉斯·克罗克福德(Douglas Crockford),事实证明,出现此警告的理由很充分。请参阅下面的答案。     
已邀请:
写给JSLint的作者道格拉斯·克罗克福德(Douglas Crockford)谈这个问题。 毕竟有一个非常合理的理由... 道格拉斯写道:   捕获变量的作用域不正确,因此我建议您在每个变量中使用不同的名称。 如果您看到类似的StackOverflow问题,您会注意到PleaseStand开始对此进行探讨。并非所有的浏览器,尤其是历史悠久的浏览器都能正确或一致地处理作用域。 JSLint认识到您的代码可能在一种浏览器中有效,但在另一种浏览器中无效,从而留下了一个非常讨厌和微妙的错误来进行跟踪。该警告是真实的。 通过使用一个不同的名称,是的,因为它不是,所以不会感到干净或简洁,这恰好是避免遇到问题的通用方法。 谢谢道格拉斯的澄清!谜团已揭开。     
该规范非常清楚,任何定义catch语句的名称都不会对周围的名称造成阴影。除此之外,我不会将这些错误视为警告。仅凭直觉,我相信这只是这些Lint工具设计者的过度热情分析。 由于catch块引入了一个新的作用域,因此使用相同的名称只会在封闭的作用域中遮盖任何相似的名称。如果您了解语义,这不一定是一件坏事。如果您在假设封闭的
err
可以访问的情况下进行编码,则您将需要更改假设。 规格 生产Catch:catch(Identifier)块的评估如下: 令C为已传递给此生产的参数。 让oldEnv成为运行中的执行上下文的LexicalEnvironment。 让catchEnv为通过将oldEnv作为参数调用NewDeclarativeEnvironment的结果。 调用catchEnv的CreateMutableBinding具体方法,将Identifier String值作为参数传递。 调用catchEnv的SetMutableBinding具体方法,并以I,C和false作为参数。请注意,在这种情况下,最后一个参数无关紧要。 将正在运行的执行上下文的LexicalEnvironment设置为catchEnv。 令B为评估Block的结果。 将正在运行的执行上下文的LexicalEnvironment设置为oldEnv。 返回B。 注意无论控件如何离开“块”,词法环境始终会恢复为其以前的状态。     
检查以下答案: JSLint抱怨我的尝试/捕获 如前所述,ѭ5打开一个新的块范围。参见https://developer.mozilla.org/en/JavaScript/Reference/Scope_Cheatsheet 确实,文档的顶部说明了它并不是全部标准,但是在ES5第12.14节中,有关执行“ 1”块的部分明确将MDC的描述定义为标准:   无论控制权如何离开LexicalEnvironment,始终将其恢复为以前的状态。     
如果以后需要引用该错误,则在顺序尝试中重用相同的参数名称可能会遇到问题。 如果调用了多个catch,则最后一个或函数作用域表达式的作用域将只有最后一个。 jsLint很保守-如果您可以防止使用唯一变量造成麻烦,为什么不使用它呢?     

要回复问题请先登录注册