【问题标题】:JavaScript: define a constant inside try / catch with strict modeJavaScript:使用严格模式在 try/catch 中定义一个常量
【发布时间】:2016-02-01 03:06:00
【问题描述】:

今天我遇到了一个奇怪的 JS 错误,在 try/catch 块中使用 const,我想更好地了解导致它的原因。

让我们看一个代码示例,价值超过一千字:

try {
  const FOO = 'bar';
  console.log('inside:', FOO);
} catch (e) {}
console.log('outside:', FOO);

这将记录:

inside: bar
outside: bar

如果我们切换到“严格模式”:

'use strict';
try {
  const FOO = 'bar';
  console.log('inside:', FOO);
} catch (e) {}
console.log('outside:', FOO);

现在同样的代码会产生错误:

ReferenceError: FOO is not defined

如果我们将 const 更改为 var

'use strict';
try {
  var foo = 'bar';
  console.log('inside:', foo);
} catch (e) {}
console.log('outside:', foo);

然后一切正常,即使在“严格模式”下:

inside: bar
outside: bar

谁能帮我理解为什么 const 分配在“严格模式”下的 try/catch 块中不起作用?

谢谢!

【问题讨论】:

  • 比较 constlet,而不是 var

标签: javascript try-catch constants ecmascript-6 strict


【解决方案1】:

您的 JavaScript 运行时部分实现了 ES6 const

ReferenceError 是您的第一个示例的预期行为,因为 const is block scoped 并且您在定义的 try 块之外访问 FOO

您使用的引擎支持const 语法,但它仅在严格模式下应用块范围语义。

当前稳定的 Chrome (46) 可以做到这一点。然而,Chrome 48 应用了带或不带严格模式的块范围。

var 不是块作用域,因此您的最后一个示例按预期工作。

【讨论】:

    【解决方案2】:

    const,由 ECMAScript 6 定义,是一个block-level variable declaration。你会得到一个ReferenceError,因为它不在try之外的范围内。

    但是,const 早在 ES6 之前就在 some engines 中引入,作为 var 的不可变对应物,具有函数级作用域行为(并且没有 TDZ)。如果您处于草率模式(您不应该如此),您可能仍会在浏览器的旧版支持中体验到这一点。

    【讨论】:

    • 我不知道旧版“const”。 MDN 脚注:“在早期版本的 Firefox 和 Chrome 以及 Safari 5.1.7 和 Opera 12.00 中,如果您使用 const 定义变量,您以后仍然可以更改其值。”
    • @joews: 是的,它只不过是var 的别名,因此为 FF 编写的脚本(相信是标准功能)至少可以在 Safari 和 Opera 中运行而不会出现语法错误同样,即使不保证不可分配性。
    • “它将继续像这样工作” - Chrome 48(当前 Canary)中的 V8 在任一模式下应用块范围(在控制台/sn-p 中测试;我找不到参考)。我想这可能会在发布前改变。
    • @joews:你说得对,引擎确实转向了 ES5 合规性。这只是一个缓慢的过程。修正了我的回答中的措辞。
    • 对于病态的好奇,这里是相关的 v8 修订历史:code.google.com/p/v8/issues/detail?id=2198
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-05
    • 2011-07-12
    • 2013-07-26
    • 2011-11-17
    • 2012-07-03
    • 1970-01-01
    相关资源
    最近更新 更多