考虑这个 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 级声明(例如 let
、 const
或 block 级函数声明)。
关于javascript - ES2015 中的 switch 语句和作用域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39001827/