ES2015中的switch语句和范围 [英] switch statement and scopes in ES2015
问题描述
请考虑此ES2015模块以及在节点v4.4.5中运行时的行为.
Consider this ES2015 module and the behavior when run in 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
子句的行为就像在外部作用域中一样.
This seems internally inconsistent to me. If the switch statement did NOT create a lexical scope, I would expect all the hey*
variables to be part of the main scope and to all behave consistently. If the switch statement did create a lexical scope, I would still expect them to be consistent, but the variables declared in the case
clauses behave like they are in a child scope, whereas the variables in the default
clause behaves like it is in the outer scope.
我的问题是switch语句中涉及任何子范围吗?如果是,那么它们的行为细节如何?
My question is are there any child scopes involved in a switch statement, and if so what are the details of how they behave?
在节点v6.4.0中,行为是不同的.看起来switch块确实确实创建了子块作用域.
In node v6.4.0, the behavior is different. It looks like the switch block does indeed create a child block scope.
ReferenceError: heyBar is not defined
这似乎更容易理解.
推荐答案
我根本无法重现您的行为.我立即得到一个 ReferenceError
(与此有关的节点是6.4.0和当前的Firefox):
I can't reproduce your behavior at all. I immediately get a ReferenceError
(Node 6.4.0 and current Firefox for that matter):
ReferenceError: heyBar is not defined
在我看来,这是正确的行为.带括号的AFAIK switch
语句确实会创建一个块,因此会成为块作用域实体的词汇作用域. case
语句本身不会创建自己的块.
Which seems like the correct behavior to me. AFAIK switch
statements with brackets DO create a block, and thus a lexical scope for block-scoped entities. The case
statements themselves do not create their own blocks.
如果在 switch
语句中使用 foo
案例扩展此示例,则它也会引发 ReferenceError
:
If we expand this example with a foo
case in the switch
statement, it throws a ReferenceError
as well:
'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
参考
5. Let blockEnv be NewDeclarativeEnvironment(oldEnv).
6. Perform BlockDeclarationInstantiation(CaseBlock, blockEnv).
其中 CaseBlock
是switch case的block语句.
Where CaseBlock
is the block statement of the switch case.
这大致翻译为:
在switch语句( switch {< -here->}
)的块中创建一个新的块环境,并实例化所有块级别的声明(例如 let
, const
或块级函数声明).
Create a new block environment in the block of the switch statement (switch { <-here-> }
) and instantiate all block level declarations (such as let
, const
or block level function declarations).
这篇关于ES2015中的switch语句和范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!