ES2015中的switch语句和范围 [英] switch statement and scopes in ES2015

查看:85
本文介绍了ES2015中的switch语句和范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑此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

参考

此处是该部分规范:11.12.11运行时语义:评估

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆