14 ECMAScript 언어: 문(Statements)과 선언(Declarations)

Syntax

Statement[Yield, Await, Return] : BlockStatement[?Yield, ?Await, ?Return] VariableStatement[?Yield, ?Await] EmptyStatement ExpressionStatement[?Yield, ?Await] IfStatement[?Yield, ?Await, ?Return] BreakableStatement[?Yield, ?Await, ?Return] ContinueStatement[?Yield, ?Await] BreakStatement[?Yield, ?Await] [+Return] ReturnStatement[?Yield, ?Await] WithStatement[?Yield, ?Await, ?Return] LabelledStatement[?Yield, ?Await, ?Return] ThrowStatement[?Yield, ?Await] TryStatement[?Yield, ?Await, ?Return] DebuggerStatement Declaration[Yield, Await] : HoistableDeclaration[?Yield, ?Await, ~Default] ClassDeclaration[?Yield, ?Await, ~Default] LexicalDeclaration[+In, ?Yield, ?Await] HoistableDeclaration[Yield, Await, Default] : FunctionDeclaration[?Yield, ?Await, ?Default] GeneratorDeclaration[?Yield, ?Await, ?Default] AsyncFunctionDeclaration[?Yield, ?Await, ?Default] AsyncGeneratorDeclaration[?Yield, ?Await, ?Default] BreakableStatement[Yield, Await, Return] : IterationStatement[?Yield, ?Await, ?Return] SwitchStatement[?Yield, ?Await, ?Return]

14.1 Statement 의미론

14.1.1 런타임 의미론: 평가

HoistableDeclaration : GeneratorDeclaration AsyncFunctionDeclaration AsyncGeneratorDeclaration
  1. empty 를 반환한다.
HoistableDeclaration : FunctionDeclaration
  1. FunctionDeclaration 의 Evaluation 결과를 ? 로 반환한다.
BreakableStatement : IterationStatement SwitchStatement
  1. newLabelSet 을 새 빈 List 로 둔다.
  2. BreakableStatement 의 LabelledEvaluation(newLabelSet) 결과를 ? 로 반환한다.

14.2 Block

Syntax

BlockStatement[Yield, Await, Return] : Block[?Yield, ?Await, ?Return] Block[Yield, Await, Return] : { StatementList[?Yield, ?Await, ?Return]opt } StatementList[Yield, Await, Return] : StatementListItem[?Yield, ?Await, ?Return] StatementList[?Yield, ?Await, ?Return] StatementListItem[?Yield, ?Await, ?Return] StatementListItem[Yield, Await, Return] : Statement[?Yield, ?Await, ?Return] Declaration[?Yield, ?Await]

14.2.1 정적 의미론: 조기 오류

Block : { StatementList }

14.2.2 런타임 의미론: 평가

Block : { }
  1. empty 를 반환한다.
Block : { StatementList }
  1. oldEnv 를 실행 중인 실행 컨텍스트의 LexicalEnvironment 로 둔다.
  2. blockEnvNewDeclarativeEnvironment(oldEnv) 로 둔다.
  3. BlockDeclarationInstantiation(StatementList, blockEnv) 수행.
  4. 실행 컨텍스트의 LexicalEnvironment 를 blockEnv 로 설정.
  5. blockValueCompletion(StatementList 평가) 로 둔다.
  6. 실행 컨텍스트의 LexicalEnvironment 를 oldEnv 로 되돌린다.
  7. blockValue 를 반환한다.
Note 1

Block 을 어떻게 빠져나오든 LexicalEnvironment 는 항상 이전 상태로 복구된다.

StatementList : StatementList StatementListItem
  1. slStatementList 의 Evaluation 결과 (?) 로 둔다.
  2. sStatementListItem 평가의 Completion 으로 둔다.
  3. UpdateEmpty(s, sl) 를 반환한다.
Note 2

StatementList 의 값은 그 안에서 마지막으로 값을 생산한 항목의 값이다. 예를 들어 아래 eval 호출은 모두 1을 반환한다:

eval("1;;;;;")
eval("1;{}")
eval("1;var a;")

14.2.3 BlockDeclarationInstantiation ( code, env )

The abstract operation BlockDeclarationInstantiation takes arguments code (a Parse Node) and env (a Declarative Environment Record) and returns unused. code 는 블록 본문에 대응하는 Parse Node 이며, env 는 바인딩이 생성될 Environment Record 이다.

Note

Block 또는 CaseBlock 이 평가될 때 새 Declarative Environment Record 가 생성되고 블록 안에 선언된 블록 스코프 변수/상수/함수/클래스에 대한 바인딩이 그 Environment Record 안에서 생성된다.

호출 시 다음 단계를 수행한다:

  1. declarationscode 의 LexicallyScopedDeclarations 로 둔다.
  2. privateEnv 를 실행 중인 실행 컨텍스트의 PrivateEnvironment 로 둔다.
  3. declarations 의 각 요소 d 에 대해
    1. d 의 BoundNames 각 요소 dn 에 대해
      1. IsConstantDeclaration(d) 가 true 이면
        1. env.CreateImmutableBinding(dn, true) 수행.
      2. 그렇지 않으면
        1. Normative Optional
          호스트가 웹 브라우저이거나 블록 수준 함수 선언 웹 레거시 호환 의미 를 지원하면
          1. env.HasBinding(dn) 이 false 이면
            1. env.CreateMutableBinding(dn, false) 수행.
        2. 그렇지 않으면
          1. env.CreateMutableBinding(dn, false) 수행.
    2. dFunctionDeclaration, GeneratorDeclaration, AsyncFunctionDeclaration, AsyncGeneratorDeclaration 중 하나라면
      1. fnd 의 BoundNames 의 유일한 요소로 둔다.
      2. fo 를 InstantiateFunctionObject(d, 인수 env, privateEnv) 로 둔다.
      3. Normative Optional
        호스트가 웹 브라우저이거나 블록 수준 함수 선언 웹 레거시 호환 의미 를 지원하면
        1. env 에서 fn 바인딩이 초기화되지 않았다면
          1. env.InitializeBinding(fn, fo) 수행.
        2. 그렇지 않으면
          1. 단언: dFunctionDeclaration.
          2. env.SetMutableBinding(fn, fo, false) 수행.
      4. 그렇지 않으면
        1. env.InitializeBinding(fn, fo) 수행.
  4. unused 반환.

14.3 선언과 변수 문(Variable Statement)

14.3.1 Let 및 Const 선언

Note

letconst 선언은 실행 중인 실행 컨텍스트의 LexicalEnvironment 에 스코프를 가지는 변수를 정의한다. 변수는 포함 Environment Record 가 초기화될 때 생성되지만 해당 변수의 LexicalBinding 이 평가되기 전에는 어떤 방식으로도 접근할 수 없다. Initializer 를 가진 LexicalBinding 으로 정의된 변수는 그 LexicalBinding 이 평가될 때 InitializerAssignmentExpression 결과 값이 할당되며, 생성 시점이 아니다. let 선언에서 Initializer 가 없는 LexicalBinding 은 평가 시 undefined 가 할당된다.

Syntax

LexicalDeclaration[In, Yield, Await] : LetOrConst BindingList[?In, ?Yield, ?Await] ; LetOrConst : let const BindingList[In, Yield, Await] : LexicalBinding[?In, ?Yield, ?Await] BindingList[?In, ?Yield, ?Await] , LexicalBinding[?In, ?Yield, ?Await] LexicalBinding[In, Yield, Await] : BindingIdentifier[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]opt BindingPattern[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]

14.3.1.1 정적 의미론: 조기 오류

LexicalDeclaration : LetOrConst BindingList ;
  • BindingList 의 BoundNames 목록에 "let" 이 포함되면 Syntax Error.
  • BindingList 의 BoundNames 목록에 중복 항목이 있으면 Syntax Error.
LexicalBinding : BindingIdentifier Initializeropt

14.3.1.2 런타임 의미론: 평가

LexicalDeclaration : LetOrConst BindingList ;
  1. BindingList 평가를 ? 로 수행.
  2. empty 반환.
BindingList : BindingList , LexicalBinding
  1. BindingList 평가를 ? 로 수행.
  2. LexicalBinding 평가 결과를 ? 로 반환.
LexicalBinding : BindingIdentifier
  1. lhs 를 ! ResolveBinding(StringValue of BindingIdentifier) 로 둔다.
  2. InitializeReferencedBinding(lhs, undefined) 수행.
  3. empty 반환.
Note

정적 의미론 규칙은 이 형태의 LexicalBindingconst 선언에서는 발생하지 않음을 보장한다.

LexicalBinding : BindingIdentifier Initializer
  1. bindingIdBindingIdentifier 의 StringValue 로 둔다.
  2. lhs 를 ! ResolveBinding(bindingId) 로 둔다.
  3. IsAnonymousFunctionDefinition(Initializer) 이 true 이면
    1. valueInitializer 의 NamedEvaluation(bindingId) 결과 (?) 로 둔다.
  4. 그렇지 않으면
    1. rhsInitializer 평가 결과 (?) 로 둔다.
    2. value 를 ? GetValue(rhs) 로 둔다.
  5. InitializeReferencedBinding(lhs, value) 수행.
  6. empty 반환.
LexicalBinding : BindingPattern Initializer
  1. rhsInitializer 평가 결과 (?) 로 둔다.
  2. value 를 ? GetValue(rhs) 로 둔다.
  3. env 를 실행 중 실행 컨텍스트의 LexicalEnvironment 로 둔다.
  4. BindingPattern 의 BindingInitialization(value, env) 결과를 ? 로 반환.

14.3.2 Variable Statement

Note

var 문은 실행 중인 실행 컨텍스트의 VariableEnvironment 에 스코프를 가지는 변수를 선언한다. Var 변수는 Environment Record 가 인스턴스화될 때 생성되며 생성과 동시에 undefined 로 초기화된다. 하나의 VariableEnvironment 스코프 내에서는 동일 BindingIdentifier 가 여러 VariableDeclaration 에 나타날 수 있으나 그것들은 하나의 변수만을 정의한다. Initializer 를 가진 VariableDeclaration 으로 정의된 변수는 선언이 실행될 때 InitializerAssignmentExpression 결과 값이 할당되며, 생성 시점이 아니다.

Syntax

VariableStatement[Yield, Await] : var VariableDeclarationList[+In, ?Yield, ?Await] ; VariableDeclarationList[In, Yield, Await] : VariableDeclaration[?In, ?Yield, ?Await] VariableDeclarationList[?In, ?Yield, ?Await] , VariableDeclaration[?In, ?Yield, ?Await] VariableDeclaration[In, Yield, Await] : BindingIdentifier[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]opt BindingPattern[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]

14.3.2.1 런타임 의미론: 평가

VariableStatement : var VariableDeclarationList ;
  1. VariableDeclarationList 평가를 ? 로 수행.
  2. empty 반환.
VariableDeclarationList : VariableDeclarationList , VariableDeclaration
  1. VariableDeclarationList 평가를 ? 로 수행.
  2. VariableDeclaration 평가 결과를 ? 로 반환.
VariableDeclaration : BindingIdentifier
  1. empty 반환.
VariableDeclaration : BindingIdentifier Initializer
  1. bindingIdBindingIdentifier 의 StringValue 로 둔다.
  2. lhs 를 ? ResolveBinding(bindingId) 로 둔다.
  3. IsAnonymousFunctionDefinition(Initializer) 이 true 이면
    1. valueInitializer 의 NamedEvaluation(bindingId) 결과 (?) 로 둔다.
  4. 그렇지 않으면
    1. rhsInitializer 평가 결과 (?) 로 둔다.
    2. value 를 ? GetValue(rhs) 로 둔다.
  5. PutValue(lhs, value) 수행.
  6. empty 반환.
Note

VariableDeclaration 이 with 문 내부에 중첩되어 있고 그 BindingIdentifier 가 with 문 Object Environment Record 의 바인딩 객체의 프로퍼티 이름과 같다면, 단계 5 는 식별자의 VariableEnvironment 바인딩 대신 그 프로퍼티에 value 를 할당한다.

VariableDeclaration : BindingPattern Initializer
  1. rhsInitializer 평가 결과 (?) 로 둔다.
  2. rVal 를 ? GetValue(rhs) 로 둔다.
  3. BindingPattern 의 BindingInitialization(rVal, undefined) 결과를 ? 로 반환.

14.3.3 구조 분해 바인딩 패턴(Destructuring Binding Patterns)

Syntax

BindingPattern[Yield, Await] : ObjectBindingPattern[?Yield, ?Await] ArrayBindingPattern[?Yield, ?Await] ObjectBindingPattern[Yield, Await] : { } { BindingRestProperty[?Yield, ?Await] } { BindingPropertyList[?Yield, ?Await] } { BindingPropertyList[?Yield, ?Await] , BindingRestProperty[?Yield, ?Await]opt } ArrayBindingPattern[Yield, Await] : [ Elisionopt BindingRestElement[?Yield, ?Await]opt ] [ BindingElementList[?Yield, ?Await] ] [ BindingElementList[?Yield, ?Await] , Elisionopt BindingRestElement[?Yield, ?Await]opt ] BindingRestProperty[Yield, Await] : ... BindingIdentifier[?Yield, ?Await] BindingPropertyList[Yield, Await] : BindingProperty[?Yield, ?Await] BindingPropertyList[?Yield, ?Await] , BindingProperty[?Yield, ?Await] BindingElementList[Yield, Await] : BindingElisionElement[?Yield, ?Await] BindingElementList[?Yield, ?Await] , BindingElisionElement[?Yield, ?Await] BindingElisionElement[Yield, Await] : Elisionopt BindingElement[?Yield, ?Await] BindingProperty[Yield, Await] : SingleNameBinding[?Yield, ?Await] PropertyName[?Yield, ?Await] : BindingElement[?Yield, ?Await] BindingElement[Yield, Await] : SingleNameBinding[?Yield, ?Await] BindingPattern[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]opt SingleNameBinding[Yield, Await] : BindingIdentifier[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]opt BindingRestElement[Yield, Await] : ... BindingIdentifier[?Yield, ?Await] ... BindingPattern[?Yield, ?Await]

14.3.3.1 런타임 의미론: PropertyBindingInitialization : 정상 완료 시 프로퍼티 키 List 또는 abrupt completion

The syntax-directed operation UNKNOWN takes UNPARSEABLE ARGUMENTS. 바인딩된 모든 프로퍼티 이름 목록을 수집한다. It is defined piecewise over the following productions:

BindingPropertyList : BindingPropertyList , BindingProperty
  1. boundNamesBindingPropertyList 의 PropertyBindingInitialization(value, environment) 결과 (?) 로 둔다.
  2. nextNamesBindingProperty 의 PropertyBindingInitialization(value, environment) 결과 (?) 로 둔다.
  3. boundNamesnextNames 의 리스트 연결을 반환.
BindingProperty : SingleNameBinding
  1. nameSingleNameBinding 의 BoundNames 유일 요소로 둔다.
  2. SingleNameBinding 의 KeyedBindingInitialization(value, environment, name) 를 ? 로 수행.
  3. « name » 반환.
BindingProperty : PropertyName : BindingElement
  1. PPropertyName 평가 결과 (?) 로 둔다.
  2. BindingElement 의 KeyedBindingInitialization(value, environment, P) 를 ? 로 수행.
  3. « P » 반환.

14.3.3.2 런타임 의미론: RestBindingInitialization : 정상 완료 시 unused 또는 abrupt completion

The syntax-directed operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It is defined piecewise over the following productions:

BindingRestProperty : ... BindingIdentifier
  1. lhs 를 ? ResolveBinding(StringValue of BindingIdentifier, environment) 로 둔다.
  2. restObjOrdinaryObjectCreate(%Object.prototype%) 로 둔다.
  3. CopyDataProperties(restObj, value, excludedNames) 수행.
  4. environmentundefined 이면 ? PutValue(lhs, restObj) 반환.
  5. InitializeReferencedBinding(lhs, restObj) 반환.

14.3.3.3 런타임 의미론: KeyedBindingInitialization : 정상 완료 시 unused 또는 abrupt completion

The syntax-directed operation UNKNOWN takes UNPARSEABLE ARGUMENTS.

Note

environmentundefined 를 전달하면 값 할당에 PutValue 연산을 사용해야 함을 의미한다. 이는 비엄격 함수의 형식 매개변수 리스트 등의 경우이며, 그때는 동일 이름 매개변수 가능성 때문에 사전 초기화된다.

It is defined piecewise over the following productions:

BindingElement : BindingPattern Initializeropt
  1. v 를 ? GetV(value, propertyName) 로 둔다.
  2. Initializer 존재하고 vundefined 이면
    1. defaultValueInitializer 평가 결과 (?) 로 둔다.
    2. v 를 ? GetValue(defaultValue) 로 설정.
  3. BindingPattern 의 BindingInitialization(v, environment) 결과를 ? 로 반환.
SingleNameBinding : BindingIdentifier Initializeropt
  1. bindingIdBindingIdentifier 의 StringValue 로 둔다.
  2. lhs 를 ? ResolveBinding(bindingId, environment) 로 둔다.
  3. v 를 ? GetV(value, propertyName) 로 둔다.
  4. Initializer 존재하고 vundefined 이면
    1. IsAnonymousFunctionDefinition(Initializer) true 이면
      1. vInitializer 의 NamedEvaluation(bindingId) 결과 (?) 로 둔다.
    2. 아니면
      1. defaultValueInitializer 평가 결과 (?) 로 둔다.
      2. v 를 ? GetValue(defaultValue) 로 둔다.
  5. environmentundefined 이면 ? PutValue(lhs, v) 반환.
  6. InitializeReferencedBinding(lhs, v) 반환.

14.4 Empty Statement

Syntax

EmptyStatement : ;

14.4.1 런타임 의미론: 평가

EmptyStatement : ;
  1. empty 반환.

14.5 Expression Statement

Syntax

ExpressionStatement[Yield, Await] : [lookahead ∉ { {, function, async [no LineTerminator here] function, class, let [ }] Expression[+In, ?Yield, ?Await] ; Note

ExpressionStatement 는 U+007B (LEFT CURLY BRACKET) 으로 시작할 수 없는데, 이는 Block 과의 모호성을 피하기 위해서이다. 또한 function 또는 class 로 시작할 수 없는데 그러면 FunctionDeclaration, GeneratorDeclaration, ClassDeclaration 과 모호하기 때문이다. async function 으로 시작할 수 없는 이유는 AsyncFunctionDeclaration 또는 AsyncGeneratorDeclaration 과 모호하기 때문이다. let [ 두 토큰 시퀀스로 시작할 수 없는 이유는 첫 LexicalBindingArrayBindingPatternlet LexicalDeclaration 과 모호하기 때문이다.

14.5.1 Runtime Semantics: Evaluation

ExpressionStatement : Expression ;
  1. exprRefExpression 평가 결과 (?) 로 둔다.
  2. GetValue(exprRef) 반환.

14.6 if

Syntax

IfStatement[Yield, Await, Return] : if ( Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] else Statement[?Yield, ?Await, ?Return] if ( Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] [lookahead ≠ else] Note
lookahead 제한 [lookahead ≠ else] 는 고전적인 “dangling else” 문제를 통상 방식으로 해결한다. 즉 어떤 else 가 어느 if 와 연관될지 모호할 때 가장 안쪽(가장 가까운)의 if 와 결합된다.

14.6.1 정적 의미론: 조기 오류

IfStatement : if ( Expression ) Statement else Statement
  • 첫 번째 Statement 에 대해 IsLabelledFunction(...) 이 true 이면 Syntax Error.
  • 두 번째 Statement 에 대해 IsLabelledFunction(...) 이 true 이면 Syntax Error.
IfStatement : if ( Expression ) Statement
  • Statement 에 대해 IsLabelledFunction(...) 이 true 이면 Syntax Error.
Note

B.3.1 에 명시된 확장이 구현된 경우에만 이 규칙을 적용하면 된다.

14.6.2 런타임 의미론: 평가

IfStatement : if ( Expression ) Statement else Statement
  1. exprRefExpression 평가 결과 (?) 로 둔다.
  2. exprValueToBoolean(? GetValue(exprRef)) 로 둔다.
  3. exprValuetrue 이면
    1. stmtCompletion 를 첫 번째 Statement 평가의 Completion 으로 둔다.
  4. 그렇지 않으면
    1. stmtCompletion 를 두 번째 Statement 평가의 Completion 으로 둔다.
  5. UpdateEmpty(stmtCompletion, undefined) 반환.
IfStatement : if ( Expression ) Statement
  1. exprRefExpression 평가 결과 (?) 로 둔다.
  2. exprValueToBoolean(? GetValue(exprRef)) 로 둔다.
  3. exprValuefalse 이면
    1. undefined 반환.
  4. 그렇지 않으면
    1. stmtCompletionStatement 평가의 Completion 으로 둔다.
    2. UpdateEmpty(stmtCompletion, undefined) 반환.

14.7 Iteration Statements

Syntax

IterationStatement[Yield, Await, Return] : DoWhileStatement[?Yield, ?Await, ?Return] WhileStatement[?Yield, ?Await, ?Return] ForStatement[?Yield, ?Await, ?Return] ForInOfStatement[?Yield, ?Await, ?Return]

14.7.1 의미론

14.7.1.1 LoopContinues ( completion, labelSet )

The abstract operation LoopContinues takes arguments completion (a Completion Record) and labelSet (a List of Strings) and returns a Boolean. It performs the following steps when called:

  1. completion 이 정상 completion 이면 true 반환.
  2. completioncontinue completion 이 아니면 false 반환.
  3. completion.[[Target]]empty 이면 true 반환.
  4. labelSetcompletion.[[Target]] 을 포함하면 true 반환.
  5. false 반환.
Note

IterationStatementStatement 부분 내부에서는 ContinueStatement 로 새 반복을 시작할 수 있다.

14.7.1.2 런타임 의미론: LoopEvaluation : 정상 완료 시 ECMAScript 언어 값 또는 abrupt completion

The syntax-directed operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It is defined piecewise over the following productions:

IterationStatement : DoWhileStatement
  1. DoWhileStatement 의 DoWhileLoopEvaluation(labelSet) 결과를 ? 로 반환.
IterationStatement : WhileStatement
  1. WhileStatement 의 WhileLoopEvaluation(labelSet) 결과를 ? 로 반환.
IterationStatement : ForStatement
  1. ForStatement 의 ForLoopEvaluation(labelSet) 결과를 ? 로 반환.
IterationStatement : ForInOfStatement
  1. ForInOfStatement 의 ForIn/OfLoopEvaluation(labelSet) 결과를 ? 로 반환.

14.7.2 do-while

Syntax

DoWhileStatement[Yield, Await, Return] : do Statement[?Yield, ?Await, ?Return] while ( Expression[+In, ?Yield, ?Await] ) ;

14.7.2.1 정적 의미론: 조기 오류

DoWhileStatement : do Statement while ( Expression ) ;
  • IsLabelledFunction(Statement) 이 true 이면 Syntax Error.
Note

B.3.1 확장이 구현된 경우에만 적용.

14.7.2.2 런타임 의미론: DoWhileLoopEvaluation : 정상 완료 시 ECMAScript 값 또는 abrupt completion

The syntax-directed operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It is defined piecewise over the following productions:

DoWhileStatement : do Statement while ( Expression ) ;
  1. Vundefined 로 둔다.
  2. 반복,
    1. stmtResultStatement 평가 Completion 으로 둔다.
    2. LoopContinues(stmtResult, labelSet) 가 false 이면 ? UpdateEmpty(stmtResult, V) 반환.
    3. stmtResult.[[Value]]empty 가 아니면 V 를 그 값으로 설정.
    4. exprRefExpression 평가 결과 (?) 로 둔다.
    5. exprValue 를 ? GetValue(exprRef) 로 둔다.
    6. ToBoolean(exprValue) 가 false 이면 V 반환.

14.7.3 while

Syntax

WhileStatement[Yield, Await, Return] : while ( Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return]

14.7.3.1 정적 의미론: 조기 오류

WhileStatement : while ( Expression ) Statement
  • IsLabelledFunction(Statement) 이 true 이면 Syntax Error.
Note

B.3.1 확장이 구현된 경우에만 적용.

14.7.3.2 런타임 의미론: WhileLoopEvaluation : 정상 완료 시 ECMAScript 값 또는 abrupt completion

The syntax-directed operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It is defined piecewise over the following productions:

WhileStatement : while ( Expression ) Statement
  1. Vundefined 로 둔다.
  2. 반복,
    1. exprRefExpression 평가 결과 (?) 로 둔다.
    2. exprValue 를 ? GetValue(exprRef) 로 둔다.
    3. ToBoolean(exprValue) 가 false 이면 V 반환.
    4. stmtResultStatement 평가 Completion 으로 둔다.
    5. LoopContinues(stmtResult, labelSet) 가 false 이면 ? UpdateEmpty(stmtResult, V) 반환.
    6. stmtResult.[[Value]]empty 가 아니면 V 갱신.

14.7.4 for

Syntax

ForStatement[Yield, Await, Return] : for ( [lookahead ≠ let [] Expression[~In, ?Yield, ?Await]opt ; Expression[+In, ?Yield, ?Await]opt ; Expression[+In, ?Yield, ?Await]opt ) Statement[?Yield, ?Await, ?Return] for ( var VariableDeclarationList[~In, ?Yield, ?Await] ; Expression[+In, ?Yield, ?Await]opt ; Expression[+In, ?Yield, ?Await]opt ) Statement[?Yield, ?Await, ?Return] for ( LexicalDeclaration[~In, ?Yield, ?Await] Expression[+In, ?Yield, ?Await]opt ; Expression[+In, ?Yield, ?Await]opt ) Statement[?Yield, ?Await, ?Return]

14.7.4.1 정적 의미론: 조기 오류

ForStatement : for ( Expressionopt ; Expressionopt ; Expressionopt ) Statement for ( var VariableDeclarationList ; Expressionopt ; Expressionopt ) Statement for ( LexicalDeclaration Expressionopt ; Expressionopt ) Statement
  • IsLabelledFunction(Statement) 이 true 이면 Syntax Error.
Note

B.3.1 확장이 구현된 경우에만 적용.

ForStatement : for ( LexicalDeclaration Expressionopt ; Expressionopt ) Statement

14.7.4.2 런타임 의미론: ForLoopEvaluation : 정상 완료 시 ECMAScript 값 또는 abrupt completion

The syntax-directed operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It is defined piecewise over the following productions:

ForStatement : for ( Expressionopt ; Expressionopt ; Expressionopt ) Statement
  1. 첫 번째 Expression 존재하면
    1. exprRef 를 그 평가 결과 (?) 로 둔다.
    2. GetValue(exprRef) 수행.
  2. 두 번째 Expression 존재하면 test 를 그 Expression 으로, 아니면 empty.
  3. 세 번째 Expression 존재하면 increment 를 그 Expression 으로, 아니면 empty.
  4. ForBodyEvaluation(test, increment, Statement, « », labelSet) 결과를 ? 로 반환.
ForStatement : for ( var VariableDeclarationList ; Expressionopt ; Expressionopt ) Statement
  1. VariableDeclarationList 평가를 ? 로 수행.
  2. 첫 번째 Expression 존재하면 test 를 그 Expression, 아니면 empty.
  3. 두 번째 Expression 존재하면 increment 를 그 Expression, 아니면 empty.
  4. ForBodyEvaluation(test, increment, Statement, « », labelSet) 결과를 ? 로 반환.
ForStatement : for ( LexicalDeclaration Expressionopt ; Expressionopt ) Statement
  1. oldEnv 를 실행 컨텍스트 LexicalEnvironment 로 둔다.
  2. loopEnvNewDeclarativeEnvironment(oldEnv) 로 둔다.
  3. isConstLexicalDeclaration 의 IsConstantDeclaration 으로 둔다.
  4. boundNamesLexicalDeclaration 의 BoundNames 로 둔다.
  5. dnboundNames 에 대해
    1. isConsttrue 이면 ! loopEnv.CreateImmutableBinding(dn, true)
    2. 아니면 ! loopEnv.CreateMutableBinding(dn, false)
  6. 실행 컨텍스트 LexicalEnvironment 를 loopEnv 로 설정.
  7. forDclLexicalDeclaration 평가 Completion 으로 둔다.
  8. forDcl 이 abrupt 면
    1. LexicalEnvironment 를 oldEnv 로 복구.
    2. forDcl 반환.
  9. isConstfalse 이면 perIterationLets = boundNames; 아니면 새 빈 List.
  10. 첫 번째 Expression 존재하면 testExpression; 아니면 empty.
  11. 두 번째 Expression 존재하면 incrementExpression; 아니면 empty.
  12. bodyResultCompletion(ForBodyEvaluation(test, increment, Statement, perIterationLets, labelSet)) 로 둔다.
  13. LexicalEnvironment 를 oldEnv 로 복구.
  14. bodyResult 반환.

14.7.4.3 ForBodyEvaluation ( test, increment, stmt, perIterationBindings, labelSet )

The abstract operation ForBodyEvaluation takes arguments test (an Expression Parse Node or empty), increment (an Expression Parse Node or empty), stmt (a Statement Parse Node), perIterationBindings (a List of Strings), and labelSet (a List of Strings) and returns 정상 완료 시 ECMAScript 값 또는 abrupt completion. It performs the following steps when called:

  1. V = undefined.
  2. CreatePerIterationEnvironment(perIterationBindings) 수행.
  3. 반복,
    1. testempty 이 아니면
      1. testRef = ? test 평가
      2. testValue = ? GetValue(testRef)
      3. ToBoolean(testValue) 가 falseV 반환.
    2. result = stmt 평가 Completion
    3. LoopContinues(result, labelSet) 가 false 면 ? UpdateEmpty(result, V) 반환.
    4. result.[[Value]]empty 아니면 V 갱신.
    5. CreatePerIterationEnvironment(perIterationBindings) 수행.
    6. incrementempty 아니면
      1. incRef = ? increment 평가
      2. GetValue(incRef) 수행.

14.7.4.4 CreatePerIterationEnvironment ( perIterationBindings )

The abstract operation CreatePerIterationEnvironment takes argument perIterationBindings (a List of Strings) and returns 정상 완료 시 unused 또는 throw completion. It performs the following steps when called:

  1. perIterationBindings 에 요소가 있으면
    1. lastIterationEnv = 실행 컨텍스트 LexicalEnvironment
    2. outer = lastIterationEnv.[[OuterEnv]]
    3. 단언: outer != null
    4. thisIterationEnv = NewDeclarativeEnvironment(outer)
    5. bnperIterationBindings 에 대해
      1. thisIterationEnv.CreateMutableBinding(bn, false)
      2. lastValue = ? lastIterationEnv.GetBindingValue(bn, true)
      3. thisIterationEnv.InitializeBinding(bn, lastValue)
    6. 실행 컨텍스트 LexicalEnvironment = thisIterationEnv
  2. unused 반환.

14.7.5 for-in, for-of, for-await-of

Syntax

ForInOfStatement[Yield, Await, Return] : for ( [lookahead ≠ let [] LeftHandSideExpression[?Yield, ?Await] in Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] for ( var ForBinding[?Yield, ?Await] in Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] for ( ForDeclaration[?Yield, ?Await] in Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] for ( [lookahead ∉ { let, async of }] LeftHandSideExpression[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] for ( var ForBinding[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] for ( ForDeclaration[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] [+Await] for await ( [lookahead ≠ let] LeftHandSideExpression[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] [+Await] for await ( var ForBinding[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] [+Await] for await ( ForDeclaration[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] ForDeclaration[Yield, Await] : LetOrConst ForBinding[?Yield, ?Await] ForBinding[Yield, Await] : BindingIdentifier[?Yield, ?Await] BindingPattern[?Yield, ?Await] Note

이 절은 부록 B.3.5 에 의해 확장된다.

14.7.5.1 정적 의미론: 조기 오류

ForInOfStatement : for ( LeftHandSideExpression in Expression ) Statement for ( var ForBinding in Expression ) Statement for ( ForDeclaration in Expression ) Statement for ( LeftHandSideExpression of AssignmentExpression ) Statement for ( var ForBinding of AssignmentExpression ) Statement for ( ForDeclaration of AssignmentExpression ) Statement for await ( LeftHandSideExpression of AssignmentExpression ) Statement for await ( var ForBinding of AssignmentExpression ) Statement for await ( ForDeclaration of AssignmentExpression ) Statement
  • IsLabelledFunction(Statement) 이 true 이면 Syntax Error.
Note

B.3.1 확장이 구현된 경우에만 적용.

ForInOfStatement : for ( LeftHandSideExpression in Expression ) Statement for ( LeftHandSideExpression of AssignmentExpression ) Statement for await ( LeftHandSideExpression of AssignmentExpression ) Statement ForInOfStatement : for ( ForDeclaration in Expression ) Statement for ( ForDeclaration of AssignmentExpression ) Statement for await ( ForDeclaration of AssignmentExpression ) Statement

14.7.5.2 정적 의미론: IsDestructuring : Boolean

The syntax-directed operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It is defined piecewise over the following productions:

MemberExpression : PrimaryExpression
  1. PrimaryExpressionObjectLiteral 또는 ArrayLiteral 이면 true 반환.
  2. 그 외 false 반환.
MemberExpression : MemberExpression [ Expression ] MemberExpression . IdentifierName MemberExpression TemplateLiteral SuperProperty MetaProperty new MemberExpression Arguments MemberExpression . PrivateIdentifier NewExpression : new NewExpression LeftHandSideExpression : CallExpression OptionalExpression
  1. false 반환.
ForDeclaration : LetOrConst ForBinding
  1. ForBinding 의 IsDestructuring 반환.
ForBinding : BindingIdentifier
  1. false 반환.
ForBinding : BindingPattern
  1. true 반환.
Note

이 절은 부록 B.3.5 에 의해 확장된다.

14.7.5.3 런타임 의미론: ForDeclarationBindingInitialization : 정상 완료 시 unused 또는 abrupt completion

The syntax-directed operation UNKNOWN takes UNPARSEABLE ARGUMENTS.

Note

environmentundefined 가 전달되면 PutValue 로 초기화해야 함을 의미한다. 이는 var 문 및 일부 비엄격 함수의 매개변수 리스트 경우 ( 10.2.11 참조 )에 해당한다. 그 경우 렉시컬 바인딩이 초기화자 평가 전 호이스팅·사전 초기화된다.

It is defined piecewise over the following productions:

ForDeclaration : LetOrConst ForBinding
  1. ForBinding 의 BindingInitialization(value, environment) 결과를 ? 로 반환.

14.7.5.4 런타임 의미론: ForDeclarationBindingInstantiation : unused

The syntax-directed operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It is defined piecewise over the following productions:

ForDeclaration : LetOrConst ForBinding
  1. ForBinding 의 BoundNames 각 name 에 대해
    1. IsConstantDeclaration(LetOrConst) 이 true 이면 ! environment.CreateImmutableBinding(name, true)
    2. 아니면 ! environment.CreateMutableBinding(name, false)
  2. unused 반환.

14.7.5.5 런타임 의미론: ForInOfLoopEvaluation : 정상 완료 시 ECMAScript 값 또는 abrupt completion

The syntax-directed operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It is defined piecewise over the following productions:

ForInOfStatement : for ( LeftHandSideExpression in Expression ) Statement
  1. keyResult = ? ForIn/OfHeadEvaluation(« », Expression, enumerate)
  2. ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement, keyResult, enumerate, assignment, labelSet) 반환.
ForInOfStatement : for ( var ForBinding in Expression ) Statement
  1. keyResult = ? ForIn/OfHeadEvaluation(« », Expression, enumerate)
  2. ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult, enumerate, var-binding, labelSet) 반환.
ForInOfStatement : for ( ForDeclaration in Expression ) Statement
  1. keyResult = ? ForIn/OfHeadEvaluation(BoundNames of ForDeclaration, Expression, enumerate)
  2. ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult, enumerate, lexical-binding, labelSet) 반환.
ForInOfStatement : for ( LeftHandSideExpression of AssignmentExpression ) Statement
  1. keyResult = ? ForIn/OfHeadEvaluation(« », AssignmentExpression, iterate)
  2. ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement, keyResult, iterate, assignment, labelSet) 반환.
ForInOfStatement : for ( var ForBinding of AssignmentExpression ) Statement
  1. keyResult = ? ForIn/OfHeadEvaluation(« », AssignmentExpression, iterate)
  2. ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult, iterate, var-binding, labelSet) 반환.
ForInOfStatement : for ( ForDeclaration of AssignmentExpression ) Statement
  1. keyResult = ? ForIn/OfHeadEvaluation(BoundNames of ForDeclaration, AssignmentExpression, iterate)
  2. ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult, iterate, lexical-binding, labelSet) 반환.
ForInOfStatement : for await ( LeftHandSideExpression of AssignmentExpression ) Statement
  1. keyResult = ? ForIn/OfHeadEvaluation(« », AssignmentExpression, async-iterate)
  2. ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement, keyResult, iterate, assignment, labelSet, async) 반환.
ForInOfStatement : for await ( var ForBinding of AssignmentExpression ) Statement
  1. keyResult = ? ForIn/OfHeadEvaluation(« », AssignmentExpression, async-iterate)
  2. ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult, iterate, var-binding, labelSet, async) 반환.
ForInOfStatement : for await ( ForDeclaration of AssignmentExpression ) Statement
  1. keyResult = ? ForIn/OfHeadEvaluation(BoundNames of ForDeclaration, AssignmentExpression, async-iterate)
  2. ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult, iterate, lexical-binding, labelSet, async) 반환.
Note

이 절은 부록 B.3.5 에 의해 확장된다.

14.7.5.6 ForIn/OfHeadEvaluation ( uninitializedBoundNames, expr, iterationKind )

The abstract operation ForIn/OfHeadEvaluation takes arguments uninitializedBoundNames (a List of Strings), expr (an Expression Parse Node or an AssignmentExpression Parse Node), and iterationKind (enumerate, iterate, or async-iterate) and returns 정상 완료 시 Iterator Record 또는 abrupt completion. It performs the following steps when called:

  1. oldEnv = 실행 컨텍스트 LexicalEnvironment
  2. uninitializedBoundNames 가 비어있지 않다면
    1. 단언: 중복 없음
    2. newEnv = NewDeclarativeEnvironment(oldEnv)
    3. nameuninitializedBoundNames 에 대해
      1. newEnv.CreateMutableBinding(name, false)
    4. LexicalEnvironment = newEnv
  3. exprRef = expr 평가 Completion
  4. LexicalEnvironment = oldEnv
  5. exprValue = ? GetValue(? exprRef)
  6. iterationKindenumerate 이면
    1. exprValueundefined 또는 null 이면
      1. Completion Record { [[Type]]: break, [[Value]]: empty, [[Target]]: empty } 반환.
    2. obj = ! ToObject(exprValue)
    3. iterator = EnumerateObjectProperties(obj)
    4. nextMethod = ! GetV(iterator, "next")
    5. Iterator Record { [[Iterator]]: iterator, [[NextMethod]]: nextMethod, [[Done]]: false } 반환.
  7. 그렇지 않으면
    1. 단언: iterate 또는 async-iterate
    2. iteratorKind = (iterationKindasync-iterate 이면 async 아니면 sync)
    3. GetIterator(exprValue, iteratorKind) 반환.

14.7.5.7 ForIn/OfBodyEvaluation ( lhs, stmt, iteratorRecord, iterationKind, lhsKind, labelSet [ , iteratorKind ] )

The abstract operation ForIn/OfBodyEvaluation takes arguments lhs (a Parse Node), stmt (a Statement Parse Node), iteratorRecord (an Iterator Record), iterationKind (enumerate or iterate), lhsKind (assignment, var-binding, or lexical-binding), and labelSet (a List of Strings) and optional argument iteratorKind (sync or async) and returns 정상 완료 시 ECMAScript 값 또는 abrupt completion. It performs the following steps when called:

  1. iteratorKind 가 없으면 sync 로 설정.
  2. oldEnv = 실행 컨텍스트 LexicalEnvironment
  3. V = undefined
  4. destructuring = IsDestructuring(lhs)
  5. destructuring true 그리고 lhsKind = assignment 이면
    1. 단언: lhsLeftHandSideExpression
    2. assignmentPattern = lhs 가 커버하는 AssignmentPattern
  6. 반복,
    1. nextResult = ? Call(iteratorRecord.[[NextMethod]], iteratorRecord.[[Iterator]])
    2. iteratorKind = async 이면 nextResult = ? Await(nextResult)
    3. nextResult 가 Object 아니면 TypeError throw
    4. done = ? IteratorComplete(nextResult)
    5. done true 이면 V 반환
    6. nextValue = ? IteratorValue(nextResult)
    7. lhsKind ∈ {assignment, var-binding} 이면
      1. destructuring true 이면
        1. lhsKind = assignment 이면
          1. status = Completion(DestructuringAssignmentEvaluation(assignmentPattern, nextValue))
        2. 아니면 (var-binding)
          1. 단언: lhsForBinding
          2. status = Completion(BindingInitialization(lhs, nextValue, undefined))
      2. destructuring false 이면
        1. lhsRef = Completion(Evaluation(lhs))
        2. lhsKind = assignment 이고 AssignmentTargetType(lhs) = web-compat 이면 ReferenceError throw
        3. lhsRef 가 abrupt 이면 status = lhsRef
        4. 아니면 status = Completion(PutValue(lhsRef.[[Value]], nextValue))
    8. 그렇지 않으면
      1. 단언: lhsKind = lexical-binding
      2. 단언: lhsForDeclaration
      3. iterationEnv = NewDeclarativeEnvironment(oldEnv)
      4. ForDeclarationBindingInstantiation(lhs, iterationEnv) 수행
      5. LexicalEnvironment = iterationEnv
      6. destructuring true 이면
        1. status = Completion(ForDeclarationBindingInitialization(lhs, nextValue, iterationEnv))
      7. 아니면
        1. 단언: 단일 이름 바인딩
        2. lhsName = BoundNames(lhs) 의 유일 요소
        3. lhsRef = ! ResolveBinding(lhsName)
        4. status = Completion(InitializeReferencedBinding(lhsRef, nextValue))
    9. status abrupt 이면
      1. LexicalEnvironment = oldEnv
      2. iteratorKind = async 이면 ? AsyncIteratorClose(iteratorRecord, status) 반환
      3. iterationKind = enumerate 이면 ? status 반환
      4. 아니면 (iterate)
        1. IteratorClose(iteratorRecord, status) 반환
    10. result = Completion(Evaluation(stmt))
    11. LexicalEnvironment = oldEnv
    12. LoopContinues(result, labelSet) false 이면
      1. iterationKind = enumerate 이면 ? UpdateEmpty(result, V) 반환
      2. 아니면 (iterate)
        1. status = Completion(UpdateEmpty(result, V))
        2. iteratorKind = async 이면 ? AsyncIteratorClose(iteratorRecord, status) 반환
        3. IteratorClose(iteratorRecord, status) 반환
    13. result.[[Value]]empty 아니면 V 갱신

14.7.5.8 런타임 의미론: 평가

BindingIdentifier : Identifier yield await
  1. bindingIdBindingIdentifier 의 StringValue 로 둔다.
  2. ResolveBinding(bindingId) 반환.

14.7.5.9 EnumerateObjectProperties ( O )

The abstract operation EnumerateObjectProperties takes argument O (an Object) and returns iterator 객체. It performs the following steps when called:

  1. O 의 열거 가능한 프로퍼티 중 String 키를 순회하는 next 메서드를 가진 iterator 객체를 반환한다. 이 객체는 ECMAScript 코드에서 직접 접근 불가하다. 순서 및 메커니즘은 아래 규칙을 준수해야 한다.

iteratorthrow, return 메서드는 null 이며 호출되지 않는다. next 메서드는 프로퍼티 키 반환 여부를 결정한다. 반환 키에는 Symbol 키 미포함. 대상 객체의 프로퍼티는 열거 중 삭제될 수 있으며 삭제된 프로퍼티는 무시된다. 열거 중 추가된 프로퍼티는 반드시 처리된다고 보장되지 않는다. 한 프로퍼티 이름은 하나의 열거에서 최대 한 번만 반환된다.

대상 객체 프로퍼티 열거에는 프로토타입 사슬의 프로퍼티도 재귀적으로 포함되지만, 이미 반환된 이름과 동일한 프로토타입 프로퍼티는 무시된다. [[Enumerable]] 값 비교는 중복 판단에 사용되지 않는다. 프로토타입 객체의 열거 가능한 이름은 그 프로토타입을 인수로 EnumerateObjectProperties 를 호출하여 얻어야 한다. 대상 객체의 own keys 는 [[OwnPropertyKeys]] 내부 메서드, 속성 서술자는 [[GetOwnProperty]] 내부 메서드를 통해 얻는다.

또한 O 나 그 프로토타입 체인 어느 객체도 Proxy/TypedArray/module namespace/exotic (구현 정의) 객체가 아니라면, 다음 사건 중 하나가 발생할 때까지 iteratorCreateForInIterator(O) 가 준 iterator 처럼 동작해야 한다:

  • O 또는 프로토타입 체인 객체의 [[Prototype]] 값 변경
  • O 또는 프로토타입 체인 객체에서 프로퍼티 제거
  • 프로토타입 체인 객체에 프로퍼티 추가
  • O 또는 체인 객체 프로퍼티의 [[Enumerable]] 값 변경
Note 1

구현은 14.7.5.10.2.1 알고리즘을 직접 구현할 필요는 없다. 위 제약 위반 전까지 동등 동작을 유지하는 임의 구현 가능.

다음은 이러한 규칙을 만족하는 ECMAScript generator 함수의 예시(정보적):

function* EnumerateObjectProperties(obj) {
  const visited = new Set();
  for (const key of Reflect.ownKeys(obj)) {
    if (typeof key === "symbol") continue;
    const desc = Reflect.getOwnPropertyDescriptor(obj, key);
    if (desc) {
      visited.add(key);
      if (desc.enumerable) yield key;
    }
  }
  const proto = Reflect.getPrototypeOf(obj);
  if (proto === null) return;
  for (const protoKey of EnumerateObjectProperties(proto)) {
    if (!visited.has(protoKey)) yield protoKey;
  }
}
Note 2
구현이 CreateForInIterator 와 일치할 필요가 없는 exotic 객체 목록은 역사적으로 구현별 차이가 있었던 경우이며 그 외에는 합의된 경우이다.

14.7.5.10 For-In Iterator 객체

For-In Iterator 는 특정 객체에 대한 특정 반복을 나타내는 객체이다. ECMAScript 코드에서 직접 접근할 수 없으며 EnumerateObjectProperties 동작 설명용이다.

14.7.5.10.1 CreateForInIterator ( object )

The abstract operation CreateForInIterator takes argument object (an Object) and returns For-In Iterator. object 의 own 및 상속된 열거 가능한 문자열 프로퍼티를 특정 순서로 순회하는 For-In Iterator 를 생성한다. It performs the following steps when called:

  1. iterator = OrdinaryObjectCreate(%ForInIteratorPrototype%, « [[Object]], [[ObjectWasVisited]], [[VisitedKeys]], [[RemainingKeys]] »)
  2. iterator.[[Object]] = object
  3. iterator.[[ObjectWasVisited]] = false
  4. iterator.[[VisitedKeys]] = 새 빈 List
  5. iterator.[[RemainingKeys]] = 새 빈 List
  6. iterator 반환

14.7.5.10.2 %ForInIteratorPrototype% 객체

%ForInIteratorPrototype% 객체:

  • 모든 For-In Iterator 객체가 상속하는 프로퍼티를 가진다.
  • ordinary object 이다.
  • [[Prototype]] 슬롯 값은 %Iterator.prototype%.
  • ECMAScript 코드에서 직접 접근할 수 없다.
  • 다음 프로퍼티를 가진다:

14.7.5.10.2.1 %ForInIteratorPrototype%.next ( )

  1. Othis 값으로 둔다.
  2. 단언: O 는 Object.
  3. 단언: OFor-In Iterator 인스턴스 내부 슬롯을 모두 가진다 (14.7.5.10.3).
  4. object = O.[[Object]]
  5. 반복,
    1. O.[[ObjectWasVisited]] false 이면
      1. keys = ? object.[[OwnPropertyKeys]]()
      2. keykeys 에 대해
        1. key 가 String 이면 O.[[RemainingKeys]] 에 추가
      3. O.[[ObjectWasVisited]] = true
    2. O.[[RemainingKeys]] 비어있지 않은 동안 반복
      1. r = 첫 요소
      2. 첫 요소 제거
      3. O.[[VisitedKeys]]r 없으면
        1. desc = ? object.[[GetOwnProperty]](r)
        2. desc != undefined 이면
          1. rO.[[VisitedKeys]] 에 추가
          2. desc.[[Enumerable]] true 이면 CreateIteratorResultObject(r, false) 반환
    3. object = ? object.[[GetPrototypeOf]]()
    4. O.[[Object]] = object
    5. O.[[ObjectWasVisited]] = false
    6. objectnull 이면 CreateIteratorResultObject(undefined, true) 반환

14.7.5.10.3 For-In Iterator 인스턴스의 프로퍼티

For-In Iterator 인스턴스는 %ForInIteratorPrototype% 을 상속하는 ordinary 객체이다. 인스턴스는 Table 36 의 내부 슬롯을 가진다.

Table 36: For-In Iterator 인스턴스의 내부 슬롯
Internal Slot Type 설명
[[Object]] an Object 현재 프로퍼티를 열거 중인 객체.
[[ObjectWasVisited]] a Boolean iterator[[OwnPropertyKeys]] 를 호출했으면 true, 아니면 false.
[[VisitedKeys]] a List of Strings 지금까지 방출된 값들.
[[RemainingKeys]] a List of Strings 현재 객체에서 아직 방출되지 않은 값들 (프로토타입 열거 전).

14.8 continue

Syntax

ContinueStatement[Yield, Await] : continue ; continue [no LineTerminator here] LabelIdentifier[?Yield, ?Await] ;

14.8.1 정적 의미론: 조기 오류

ContinueStatement : continue ; continue LabelIdentifier ;
  • ContinueStatement 가 (함수나 static 초기화 블록 경계를 넘지 않고) 직접 또는 간접적으로 IterationStatement 내에 중첩되지 않았다면 Syntax Error.

14.8.2 런타임 의미론: 평가

ContinueStatement : continue ;
  1. Completion Record { [[Type]]: continue, [[Value]]: empty, [[Target]]: empty } 반환.
ContinueStatement : continue LabelIdentifier ;
  1. label = LabelIdentifier 의 StringValue
  2. Completion Record { [[Type]]: continue, [[Value]]: empty, [[Target]]: label } 반환.

14.9 break

Syntax

BreakStatement[Yield, Await] : break ; break [no LineTerminator here] LabelIdentifier[?Yield, ?Await] ;

14.9.1 정적 의미론: 조기 오류

BreakStatement : break ;

14.9.2 런타임 의미론: 평가

BreakStatement : break ;
  1. Completion Record { [[Type]]: break, [[Value]]: empty, [[Target]]: empty } 반환.
BreakStatement : break LabelIdentifier ;
  1. label = LabelIdentifier 의 StringValue
  2. Completion Record { [[Type]]: break, [[Value]]: empty, [[Target]]: label } 반환.

14.10 return

Syntax

ReturnStatement[Yield, Await] : return ; return [no LineTerminator here] Expression[+In, ?Yield, ?Await] ; Note

return 문은 함수를 종료하고(대부분 경우) 호출자에게 값을 반환한다. Expression 이 없으면 반환 값은 undefined. 있으면 그 표현식의 값. return 문이 주변 컨텍스트에 따라 실제로 호출자에게 값을 반환하지 않을 수도 있다. 예: try 블록 내 returnCompletion Recordfinally 블록 평가 중 다른 Completion Record 로 대체될 수 있다.

14.10.1 런타임 의미론: 평가

ReturnStatement : return ;
  1. ReturnCompletion(undefined) 반환.
ReturnStatement : return Expression ;
  1. exprRef = Expression 평가 결과 (?)
  2. exprValue = ? GetValue(exprRef)
  3. GetGeneratorKind() 가 async 이면 exprValue = ? Await(exprValue)
  4. ReturnCompletion(exprValue) 반환.
Legacy

14.11 with

Note 1

레거시 with 문 사용은 새로운 ECMAScript 코드에서 권장되지 않는다. 엄격/비엄격 모두 허용되는 구조 분해 할당 등의 대안을 고려하라.

Syntax

WithStatement[Yield, Await, Return] : with ( Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] Note 2

with 문은 계산된 객체에 대한 Object Environment Record 를 실행 컨텍스트의 렉시컬 환경에 추가한 후 그 확장된 환경으로 문을 실행하고 마지막에 원래 환경을 복구한다.

14.11.1 정적 의미론: 조기 오류

WithStatement : with ( Expression ) Statement
  • IsStrict(this production) true 이면 Syntax Error.
  • IsLabelledFunction(Statement) true 이면 Syntax Error.
Note

두 번째 규칙은 B.3.1 확장이 구현된 경우에만 적용.

14.11.2 런타임 의미론: 평가

WithStatement : with ( Expression ) Statement
  1. val = Expression 평가 결과 (?)
  2. obj = ? ToObject(? GetValue(val))
  3. oldEnv = 현재 LexicalEnvironment
  4. newEnv = NewObjectEnvironment(obj, true, oldEnv)
  5. LexicalEnvironment = newEnv
  6. C = Statement 평가 Completion
  7. LexicalEnvironment = oldEnv
  8. UpdateEmpty(C, undefined) 반환
Note

임의의 경로로 embedded Statement 를 빠져나와도(정상/abrupt) LexicalEnvironment 는 항상 복원된다.

14.12 switch

Syntax

SwitchStatement[Yield, Await, Return] : switch ( Expression[+In, ?Yield, ?Await] ) CaseBlock[?Yield, ?Await, ?Return] CaseBlock[Yield, Await, Return] : { CaseClauses[?Yield, ?Await, ?Return]opt } { CaseClauses[?Yield, ?Await, ?Return]opt DefaultClause[?Yield, ?Await, ?Return] CaseClauses[?Yield, ?Await, ?Return]opt } CaseClauses[Yield, Await, Return] : CaseClause[?Yield, ?Await, ?Return] CaseClauses[?Yield, ?Await, ?Return] CaseClause[?Yield, ?Await, ?Return] CaseClause[Yield, Await, Return] : case Expression[+In, ?Yield, ?Await] : StatementList[?Yield, ?Await, ?Return]opt DefaultClause[Yield, Await, Return] : default : StatementList[?Yield, ?Await, ?Return]opt

14.12.1 정적 의미론: 조기 오류

SwitchStatement : switch ( Expression ) CaseBlock

14.12.2 런타임 의미론: CaseBlockEvaluation : 정상 완료 시 ECMAScript 값 또는 abrupt completion

The syntax-directed operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It is defined piecewise over the following productions:

CaseBlock : { }
  1. undefined 반환.
CaseBlock : { CaseClauses }
  1. V = undefined
  2. A = CaseClausesCaseClause 리스트 (소스 순서)
  3. found = false
  4. CA 에 대해
    1. found false 이면 found = ? CaseClauseIsSelected(C, input)
    2. found true 이면
      1. R = C 평가 Completion
      2. R.[[Value]]empty 아니면 V 갱신
      3. R abrupt 이면 ? UpdateEmpty(R, V) 반환
  5. V 반환.
CaseBlock : { CaseClausesopt DefaultClause CaseClausesopt }
  1. V = undefined
  2. CaseClauses 존재하면 A = 그 CaseClause 리스트; 아니면 새 빈 List
  3. found = false
  4. CA 에 대해
    1. found false 이면 found = ? CaseClauseIsSelected(C, input)
    2. found true 이면
      1. R = C 평가 Completion
      2. R.[[Value]] empty 아니면 V 갱신
      3. R abrupt 이면 ? UpdateEmpty(R, V) 반환
  5. foundInB = false
  6. 두 번째 CaseClauses 존재하면 B = 그 리스트; 아니면 빈 List
  7. found false 이면
    1. CB 에 대해
      1. foundInB false 이면 foundInB = ? CaseClauseIsSelected(C, input)
      2. foundInB true 이면
        1. R = C 평가 Completion
        2. R.[[Value]] empty 아니면 V 갱신
        3. R abrupt 이면 ? UpdateEmpty(R, V) 반환
  8. foundInB true 이면 V 반환
  9. defaultR = DefaultClause 평가 Completion
  10. defaultR.[[Value]] empty 아니면 V 갱신
  11. defaultR abrupt 이면 ? UpdateEmpty(defaultR, V) 반환
  12. (두 번째 CaseClauses 전체 재순회)
  13. CB 에 대해
    1. R = C 평가 Completion
    2. R.[[Value]] empty 아니면 V 갱신
    3. R abrupt 이면 ? UpdateEmpty(R, V) 반환
  14. V 반환

14.12.3 CaseClauseIsSelected ( C, input )

The abstract operation CaseClauseIsSelected takes arguments C (a CaseClause Parse Node) and input (an ECMAScript language value) and returns 정상 완료 시 Boolean 또는 abrupt completion. Cinput 과 일치하는지 결정한다. It performs the following steps when called:

  1. 단언: C CaseClause : case Expression : StatementListopt 인스턴스.
  2. exprRef = CExpression 평가 결과 (?)
  3. clauseSelector = ? GetValue(exprRef)
  4. IsStrictlyEqual(input, clauseSelector) 반환.
Note

이 연산은 CStatementList (있다면)를 실행하지 않는다. CaseBlock 알고리즘은 반환값을 사용해 어느 StatementList 부터 실행할지 결정한다.

14.12.4 런타임 의미론: 평가

SwitchStatement : switch ( Expression ) CaseBlock
  1. exprRef = Expression 평가 결과 (?)
  2. switchValue = ? GetValue(exprRef)
  3. oldEnv = 현재 LexicalEnvironment
  4. blockEnv = NewDeclarativeEnvironment(oldEnv)
  5. BlockDeclarationInstantiation(CaseBlock, blockEnv) 수행
  6. LexicalEnvironment = blockEnv
  7. R = CaseBlockEvaluation(CaseBlock, switchValue) 의 Completion
  8. LexicalEnvironment = oldEnv
  9. R 반환
Note

SwitchStatement 를 어떻게 빠져나오든 LexicalEnvironment 는 복구된다.

CaseClause : case Expression :
  1. empty 반환.
CaseClause : case Expression : StatementList
  1. StatementList 평가 결과를 ? 로 반환.
DefaultClause : default :
  1. empty 반환.
DefaultClause : default : StatementList
  1. StatementList 평가 결과를 ? 로 반환.

14.13 Labelled Statements

Syntax

LabelledStatement[Yield, Await, Return] : LabelIdentifier[?Yield, ?Await] : LabelledItem[?Yield, ?Await, ?Return] LabelledItem[Yield, Await, Return] : Statement[?Yield, ?Await, ?Return] FunctionDeclaration[?Yield, ?Await, ~Default] Note

Statement 는 레이블로 접두될 수 있다. 레이블 문은 레이블된 break/continue 와 함께 사용된다. ECMAScript 에는 goto 가 없다. StatementLabelledStatement 의 일부가 될 수 있고 이것이 또 다른 LabelledStatement 의 일부가 되는 식으로 중첩될 수 있다. 이렇게 도입된 레이블 집합을 개별 문 의미론에서 “current label set” 이라 부른다.

14.13.1 정적 의미론: 조기 오류

LabelledItem : FunctionDeclaration
  • 이 생성물에 매칭되는 소스 텍스트가 있다면 Syntax Error — 단, 그 소스가 비엄격 코드이고 호스트레이블된 함수 선언 를 지원하면 예외.

14.13.2 정적 의미론: IsLabelledFunction ( stmt: a Statement Parse Node, ): Boolean

The abstract operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It performs the following steps when called:

  1. stmtLabelledStatement 아니면 false 반환.
  2. item = stmtLabelledItem
  3. item LabelledItem : FunctionDeclaration 이면 true 반환.
  4. subStmt = itemStatement
  5. IsLabelledFunction(subStmt) 반환.

14.13.3 런타임 의미론: 평가

LabelledStatement : LabelIdentifier : LabelledItem
  1. LabelledStatement 의 LabelledEvaluation(« ») 결과를 ? 로 반환.

14.13.4 런타임 의미론: LabelledEvaluation : 정상 완료 시 ECMAScript 값 또는 empty, 또는 abrupt completion

The syntax-directed operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It is defined piecewise over the following productions:

BreakableStatement : IterationStatement
  1. stmtResult = Completion(LoopEvaluation(IterationStatement, labelSet))
  2. stmtResultbreak completion 이고 stmtResult.[[Target]]empty 이면
    1. stmtResult.[[Value]]empty 이면 stmtResult = NormalCompletion(undefined)
    2. 아니면 stmtResult = NormalCompletion(stmtResult.[[Value]])
  3. stmtResult 반환
BreakableStatement : SwitchStatement
  1. stmtResult = Completion(Evaluation(SwitchStatement))
  2. stmtResultbreak completion 이고 stmtResult.[[Target]]empty 이면
    1. stmtResult.[[Value]] empty 이면 stmtResult = NormalCompletion(undefined) 아니면 NormalCompletion(stmtResult.[[Value]])
  3. stmtResult 반환
Note 1

BreakableStatement 는 레이블 없는 BreakStatement 로 빠져나올 수 있는 문이다.

LabelledStatement : LabelIdentifier : LabelledItem
  1. label = LabelIdentifier 의 StringValue
  2. newLabelSet = labelSet ⧺ « label »
  3. stmtResult = Completion(LabelledEvaluation(LabelledItem, newLabelSet))
  4. stmtResultbreak completion 이고 stmtResult.[[Target]] = label 이면
    1. stmtResult = NormalCompletion(stmtResult.[[Value]])
  5. stmtResult 반환
LabelledItem : FunctionDeclaration
  1. FunctionDeclaration 평가 결과를 ? 로 반환.
Statement : BlockStatement VariableStatement EmptyStatement ExpressionStatement IfStatement ContinueStatement BreakStatement ReturnStatement WithStatement ThrowStatement TryStatement DebuggerStatement
  1. Statement 평가 결과를 ? 로 반환.
Note 2

Statement 의 production 중 LabelledEvaluation 에 특별한 의미론을 갖는 것은 BreakableStatementLabelledStatement 두 가지뿐이다.

14.14 throw

Syntax

ThrowStatement[Yield, Await] : throw [no LineTerminator here] Expression[+In, ?Yield, ?Await] ;

14.14.1 런타임 의미론: 평가

ThrowStatement : throw Expression ;
  1. exprRef = Expression 평가 결과 (?)
  2. exprValue = ? GetValue(exprRef)
  3. ThrowCompletion(exprValue) 반환.

14.15 try

Syntax

TryStatement[Yield, Await, Return] : try Block[?Yield, ?Await, ?Return] Catch[?Yield, ?Await, ?Return] try Block[?Yield, ?Await, ?Return] Finally[?Yield, ?Await, ?Return] try Block[?Yield, ?Await, ?Return] Catch[?Yield, ?Await, ?Return] Finally[?Yield, ?Await, ?Return] Catch[Yield, Await, Return] : catch ( CatchParameter[?Yield, ?Await] ) Block[?Yield, ?Await, ?Return] catch Block[?Yield, ?Await, ?Return] Finally[Yield, Await, Return] : finally Block[?Yield, ?Await, ?Return] CatchParameter[Yield, Await] : BindingIdentifier[?Yield, ?Await] BindingPattern[?Yield, ?Await] Note

try 문은 런타임 오류나 throw 등 예외 상황이 발생할 수 있는 코드 블록을 감싼다. catch 절은 예외 처리 코드를 제공한다. catch 절이 예외를 잡으면 CatchParameter 에 그 예외 값이 바인딩된다.

14.15.1 정적 의미론: 조기 오류

Catch : catch ( CatchParameter ) Block

14.15.2 런타임 의미론: CatchClauseEvaluation : 정상 완료 시 ECMAScript 값 또는 empty, 또는 abrupt completion

The syntax-directed operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It is defined piecewise over the following productions:

Catch : catch ( CatchParameter ) Block
  1. oldEnv = 현재 LexicalEnvironment
  2. catchEnv = NewDeclarativeEnvironment(oldEnv)
  3. CatchParameter 의 BoundNames 각 argName 에 대해
    1. catchEnv.CreateMutableBinding(argName, false)
  4. LexicalEnvironment = catchEnv
  5. status = Completion(BindingInitialization(CatchParameter, thrownValue, catchEnv))
  6. status abrupt 이면
    1. LexicalEnvironment = oldEnv
    2. status 반환
  7. B = Block 평가 Completion
  8. LexicalEnvironment = oldEnv
  9. B 반환
Catch : catch Block
  1. Block 평가 결과를 ? 로 반환.
Note

Block 을 어떻게 빠져나오든 LexicalEnvironment 는 복구된다.

14.15.3 런타임 의미론: 평가

TryStatement : try Block Catch
  1. B = Block 평가 Completion
  2. Bthrow completion 이면 C = Completion(CatchClauseEvaluation(Catch, B.[[Value]])); 아니면 C = B
  3. UpdateEmpty(C, undefined) 반환
TryStatement : try Block Finally
  1. B = Block 평가 Completion
  2. F = Finally 평가 Completion
  3. Fnormal completion 이면 F = B
  4. UpdateEmpty(F, undefined) 반환
TryStatement : try Block Catch Finally
  1. B = Block 평가 Completion
  2. Bthrow completion 이면 C = Completion(CatchClauseEvaluation(Catch, B.[[Value]])); 아니면 C = B
  3. F = Finally 평가 Completion
  4. Fnormal completion 이면 F = C
  5. UpdateEmpty(F, undefined) 반환

14.16 debugger

Syntax

DebuggerStatement : debugger ;

14.16.1 런타임 의미론: 평가

Note

DebuggerStatement 를 평가하면 구현이 디버거 실행 시 중단점을 걸 수 있게 할 수 있다. 디버거가 없거나 비활성화된 경우 관찰 가능한 효과가 없다.

DebuggerStatement : debugger ;
  1. 구현 정의 디버깅 기능이 활성화되어 있으면
    1. 구현 정의 디버깅 동작 수행.
    2. 구현 정의 Completion Record 반환.
  2. 그렇지 않으면
    1. empty 반환.