switch
본문은 새로운 블록 범위를 만듭니다. 각 개별 case
절 또는 default
절은 자동으로 새 블록 범위를 작성하지 않습니다.
범위 지정 및 switch
문을 이해하기위한 확실한 참조는 물론 ES2016 specification입니다. 그러나 그것이 정말로 무엇을 말하고 있는지를 알아내는 일이 있습니다. 내가 그 명세에서 따를 수있는 것을 통해 당신을 걸어 나갈 것이다.
CaseBlock:
{ CaseClauses }
{ CaseClauses DefaultClause CaseClauses }
CaseClauses:
CaseClause
CaseClauses CaseClause
CaseClause:
case Expression : StatementList
DefaultClause:
default : StatementList
는 그래서 CaseBlock
가하십시오 CaseBlock이있다,
SwitchStatement:
switch (Expression) CaseBlock
그리고 :
정의 중요한 용어
는 우선, 스위치 문이 정의된다 switch
문 (모든 경우를 포함하는 코드)의 본문
이것은 우리가 기대하는 바이지만 위에 정의 된 CaseBlock
이라는 용어는 다른 스펙 참조에서 중요합니다.
CaseBlock 그런 다음 13.2.14 Runtime Semantics: BlockDeclarationInstantiation(code, env), 우리는 CaseBlock 생성되는 새로운 범주를 일으키는 것을 알 수
새로운 범위를 생성한다. 블록 또는 CaseBlock 생산 새로운 선언적 환경 레코드 평가
은 환경의 인스턴스화 만들어 블록마다 바인딩 블록 선언 변수, 상수 함수 발생기 함수 또는 클래스 범위가 기록. CaseBlock
이후
는 switch
문의 본문이이 switch
문의 본문은 하나 개의 새로운 블록 범위 (새로운 /리스 CONST 선언 컨테이너)를 생성하는 수단이다.
CaseClause는 기존 범위 (자신의 범위를 작성하지 않습니다)
그런 다음, 13.12.6 Static Semantics: LexicallyScopedDeclarations에, 그것은 어휘 범위 선언은 구문 분석시에는 인터프리터에 의해 수집하는 방법에 대해 설명을 추가합니다. 여기 사양의 실제 텍스트입니다 (설명이 따를 것이다) :
CaseBlock : {CaseClauses DefaultClause CaseClauses}
- 첫 CaseClauses가있는 경우, 선언이 첫 번째 CaseClauses의 LexicallyScopedDeclarations하자.
- 다른 예외는 선언을 새로운 빈 목록으로 만듭니다.
- DefaultClause의 LexicallyScopedDeclarations 요소를 선언에 추가합니다.
- 두 번째 CaseClauses가 없으면 선언을 반환합니다.
- Else는 두 번째 CaseClauses의 LexicallyScopedDeclarations 요소를 선언에 추가 한 결과를 반환합니다.
CaseClauses : CaseClauses CaseClause 선언 CaseClauses의 LexicallyScopedDeclarations 수
- 하자.
- CaseClause의 LexicallyScopedDeclarations 요소를 선언에 추가합니다.
- 선언을 반환합니다.
CaseClause : CASE 식 :
- StatementList가 있으면 StatementList는 StatementList의 LexicallyScopedDeclarations를 반환한다.
- 그렇지 않으면 새로운 빈 목록을 반환합니다.
DefaultClause : 기본 :
- StatementList가 존재하는 경우 StatementList는 StatementList의 LexicallyScopedDeclarations을 반환합니다.
- 그렇지 않으면 새로운 빈 목록을 반환합니다.
그래서, 기본적으로 어떤이가 말하는 것은 처음 caseClause는 LexicallyScopedDeclarations 객체를 생성한다는 것이다. 그리고 그 뒤에 오는 각 DefaultClause 또는 CaseClause는 해당 선언 객체에 추가됩니다. 이것은 스펙이 범위 내에서 모든 선언을 작성하는 방법을 설명합니다.
CaseClause
은 기존 선언 개체에 추가되지만 자체 선언은 만들지 않습니다. 즉, 자체 범위를 만들지 않고 대신 포함 범위를 사용합니다.
물론 CaseClause
내에 블록을 정의 할 수 있으며 해당 블록은 자체 범위가되지만 CaseClause
에는 블록 선언이 필요하지 않으므로 기본적으로 새 범위를 만들지 않습니다.
런타임 의미 : 평가
그런 일이 13.12.11 Runtime Semantics: Evaluation
SwitchStatement에서 런타임에 작동하는 방법에 대한 자세한 설명이 있습니다 : 수 exprRef 스위치 (표현) CaseBlock
- 하자가 표현식을 평가 한 결과
- switchValue를 사용 하시겠습니까? GetValue (exprRef).
- oldEnv를 실행중인 실행 컨텍스트의 LexicalEnvironment로 설정합니다.
- blockEnv를 NewDeclarativeEnvironment (oldEnv)로 둡니다.
- BlockDeclarationInstantiation (CaseBlock, blockEnv)을 수행하십시오.
- 실행중인 실행 컨텍스트의 LexicalEnvironment를 blockEnv로 설정하십시오.
- R을 switchValue 인수로 CaseBlock의 CaseBlockEvaluation을 수행 한 결과라고합시다.
- 실행중인 실행 컨텍스트의 LexicalEnvironment를 oldEnv로 설정하십시오. 여기
- 복귀 R.
수술 단계는 새로운 블록 환경이 생성된다 CaseBlock
4-5 단계이다. 13.12.11의 텍스트에서 계속하면 CaseBlock
안에 CaseClause
에 대한 새로운 블록 환경이 생성되지 않습니다.
CaseClause : CASE 식 : StatementList
- 돌아 StatementList을 평가 한 결과.
그래서, 당신이 가지고 있습니다. CaseBlock
은 새 블록 범위를 만듭니다. A CaseClause
은 (사용자가 CaseClause
내에서 명시 적으로 블록을 정의하지 않는 한) 없습니다.
Btw, 각각의 경우에 블록 스코프를 추가하면 케이스 별 범위를 만들 수 있습니다 :'case 'bar': {const heyBar = 'HEY_BAR'; 휴식}'. – ftor