javascript - ES2015 中的 switch 语句和作用域

标签 javascript node.js ecmascript-6 v8

考虑这个 ES2015 模块和在 Node v4.4.5 中运行时的行为。

'use strict'

const outer = 1

switch ('foo') {
  case 'bar':
    const heyBar = 'HEY_BAR'
    break
  case 'baz':
    const heyBaz = 'HEY_BAZ'
    break
  default:
    const heyDefault = 'HEY_DEFAULT'
}
console.log(
  outer, // 1, makes sense, same top-level scope
  heyBar, // undefined. huh? I thought switch did NOT create a child scope
  heyBaz, // undefined. huh? I thought switch did NOT create a child scope
  heyDefault) // 'HEY_DEFAULT' makes sense

这在我看来内部不一致。如果 switch 语句没有创建词法作用域,我希望所有 hey* 变量都是主作用域的一部分,并且所有行为都一致。如果 switch 语句确实创建了一个词法作用域,我仍然希望它们是一致的,但是在 case 子句中声明的变量表现得就像它们在子作用域中一样,而在 >default 子句的行为就像在外部范围内一样。

我的问题是switch 语句中是否涉及任何子作用域,如果有,它们的行为细节是什么?

在 Node v6.4.0 中,行为有所不同。看起来 switch block 确实创建了一个子 block 作用域。

ReferenceError: heyBar is not defined

这似乎更容易理解。

最佳答案

我根本无法重现您的行为。我立即得到 ReferenceError (就此而言,Node 6.4.0 和当前的 Firefox):

ReferenceError: heyBar is not defined

这对我来说似乎是正确的行为。据我所知switch带括号的语句 DO 创建一个 block ,从而为 block 范围的实体创建一个词法范围。 case语句本身不会创建自己的 block 。

如果我们用 foo 扩展这个例子switch 中的案例语句,它抛出一个 ReferenceError还有:

'use strict'

const outer = 1

switch ('foo') {
  case 'bar':
    const heyBar = 'HEY_BAR'
    break
  case 'baz':
    const heyBaz = 'HEY_BAZ'
    break
  case 'foo':
    const heyFoo = 'HEY_FOO'
    break
  default:
    const heyDefault = 'HEY_DEFAULT'
}
console.log(
  outer,
  heyFoo,
  heyBar,
  heyBaz,
  heyDefault) // ReferenceError: heyFoo is not defined

引用

Here is the section in the spec: 13.12.11 Runtime Semantics: Evaluation

5. Let blockEnv be NewDeclarativeEnvironment(oldEnv).
6. Perform BlockDeclarationInstantiation(CaseBlock, blockEnv).

在哪里 CaseBlock 是 switch case 的 block 语句。

这大致转化为:

在 switch 语句 ( switch { <-here-> } ) 的 block 中创建一个新的 block 环境,并实例化所有 block 级声明(例如 letconst 或 block 级函数声明)。

关于javascript - ES2015 中的 switch 语句和作用域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39001827/

相关文章:

javascript - Firebase(网络)创建/更新与当前不同的用户

javascript - 在nodejs中使用twitter oauth时无法获取/auth/twitter/callback

javascript - 为什么这个 MongoDB 错误函数不能正常工作?

javascript - 学生平均水平 - JavaScript 无响应

javascript - 将 HTML/CSS 转换为图像的更好方法

ios - Socket.IO-Client-Swift 无法连接到nodejs socket.io 服务器

node.js - NGINX 未正确设置 X-Forwarded-For

javascript - ES6 继承 : uses `super` to access the properties of the parent class

javascript - 如果我使用 ES6,我需要 browserify 吗?

javascript - 如何从元素绑定(bind)数据 Web 组件