- 12 Statements
-
Syntax
- Statement :
- Block
VariableStatement
EmptyStatement
ExpressionStatement
IfStatement
IterationStatement
ContinueStatement
BreakStatement
ReturnStatement
WithStatement
LabelledStatement
SwitchStatement
ThrowStatement
TryStatement
Semantics
A Statement can be part of a LabelledStatement, which itself can be part of a LabelledStatement,
and so on. The labels introduced this way are collectively referred to as the "current label set" when describing the
semantics of individual statements. A LabelledStatement has no semantic meaning other than the introduction of a
label to a label set. The label set of an IterationStatement or a SwitchStatement initially
contains the single element empty. The label set of any other statement is initially empty.
- 12.1 Block
-
Syntax
- Block :
- { StatementListopt }
- StatementList :
- Statement
StatementList Statement
Semantics
The production Block : {} is evaluated as follows:
1.Return (normal, empty, empty).
The production Block : { StatementList } is evaluated as follows:
1.Evaluate StatementList.
2.Return Result(1).
The production StatementList : Statement is evaluated as follows:
1.Evaluate Statement.
2.If an exception was thrown, return (throw, V, empty) where V is the exception. (Execution now proceeds as if
no exception were thrown.)
3.Return Result(1).
The production StatementList : StatementList Statement is evaluated as follows:
1.Evaluate StatementList.
2.If Result(1) is an abrupt completion, return Result(1).
3.Evaluate Statement.
4.If an exception was thrown, return (throw, V, empty) where V is the exception. (Execution now proceeds as if
no exception were thrown.)
5.If Result(3). value is empty, let V = Result(1). value, otherwise let V = Result(3). value.
6.Return (Result(3). type, V, Result(3). target).
- 12.2 Variable statement
-
Syntax
- VariableStatement :
- var VariableDeclarationList ;
- VariableDeclarationList :
- VariableDeclaration
VariableDeclarationList , VariableDeclaration
- VariableDeclarationListNoIn :
- VariableDeclarationNoIn
VariableDeclarationListNoIn , VariableDeclarationNoIn
- VariableDeclaration :
- Identifier Initialiseropt
- VariableDeclarationNoIn :
- Identifier InitialiserNoInopt
- Initialiser :
- = AssignmentExpression
- InitialiserNoIn :
- = AssignmentExpressionNoIn
Description
If the variable statement occurs inside a FunctionDeclaration, the variables are defined with function-local
scope in that function, as described in s10.1.3. Otherwise, they are defined with global scope
(that is, they are created as members of the global object, as described in 10.1.3) using
property attributes { DontDelete }. Variables are created when the execution scope is entered. A Block does not
define a new execution scope. Only Program and FunctionDeclaration produce a new scope. Variables are
initialised to undefined when created. A variable with an Initialiser is assigned the value of its
AssignmentExpression when the VariableStatement is executed, not when the variable is created.
Semantics
The production VariableStatement : var VariableDeclarationList ; is
evaluated as follows:
1.Evaluate VariableDeclarationList.
2.Return (normal, empty, empty).
The production VariableDeclarationList :VariableDeclaration is evaluated as follows:
1.Evaluate VariableDeclaration.
The production VariableDeclarationList : VariableDeclarationList ,
VariableDeclaration is evaluated as follows:
1. Evaluate VariableDeclarationList.
2. Evaluate VariableDeclaration.
The production VariableDeclaration : Identifier is evaluated as follows:
1.Return a string value containing the same sequence of characters as in the Identifier.
The production VariableDeclaration : Identifier Initialiser is evaluated as follows:
1.Evaluate Identifier as described in 11.1.2.
2.Evaluate Initialiser.
3.Call GetValue(Result(2)).
4.Call PutValue(Result(1), Result(3)).
5.Return a string value containing the same sequence of characters as in the Identifier.
The production Initialiser : = AssignmentExpression is evaluated as follows:
1.Evaluate AssignmentExpression.
2.Return Result(1).
The VariableDeclarationListNoIn, VariableDeclarationNoIn and InitialiserNoIn productions are evaluated
in the same manner as the VariableDeclarationList, VariableDeclaration and Initialiser productions except
that the contained VariableDeclarationListNoIn, VariableDeclarationNoIn, InitialiserNoIn and
AssignmentExpressionNoIn are evaluated instead of the contained VariableDeclarationList, VariableDeclaration,
Initialiser and AssignmentExpression, respectively.
- 12.3 Empty Statement
-
Syntax
- EmptyStatement :
- ;
Semantics
The production EmptyStatement : ; is evaluated as follows:
1.Return (normal, empty, empty).
- 12.4 Expression Statement
-
Syntax
- ExpressionStatement :
- [lookahead ∉ {{, function}] Expression ;
Note that an ExpressionStatement cannot start with an opening curly brace because that might make it ambiguous
with a Block. Also, an ExpressionStatement cannot start with the function keyword because that
might make it ambiguous with a FunctionDeclaration.
Semantics
The production ExpressionStatement : [lookahead ∉ {{, function}] Expression; is
evaluated as follows:
1.Evaluate Expression.
2.Call GetValue(Result(1)).
3.Return (normal, Result(2), empty).
- 12.5 The if Statement
-
Syntax
- IfStatement :
- if ( Expression ) Statement else Statement
if ( Expression ) Statement
Each else for which the choice of associated if is ambiguous shall be associated with
the nearest possible if that would otherwise have no corresponding else.
Semantics
The production IfStatement : if ( Expression ) Statement
else Statement is evaluated as follows:
1.Evaluate Expression.
2.Call GetValue(Result(1)).
3.Call ToBoolean(Result(2)).
4.If Result(3) is false, go to step 7.
5. Evaluate the first Statement.
6.Return Result(5).
7.Evaluate the second Statement.
8.Return Result(7).
The production IfStatement : if ( Expression ) Statement is
evaluated as follows:
1.Evaluate Expression.
2.Call GetValue(Result(1)).
3.Call ToBoolean(Result(2)).
4.If Result(3) is false, return (normal, empty, empty).
5.Evaluate Statement.
6.Return Result(5).
- 12.6 Iteration Statements
-
An iteration statement consists of a header (which consists of a keyword and a parenthesised control
construct) and a body (which consists of a Statement).
Syntax
- IterationStatement :
- do Statement while ( Expression );
while ( Expression ) Statement
for ( ExpressionNoInopt; Expressionopt ;
Expressionopt ) Statement
for (var VariableDeclarationListNoIn; Expressionopt ;
Expressionopt ) Statement
for ( LeftHandSideExpression in Expression )
Statement
for (var VariableDeclarationNoIn in Expression )
Statement
- 12.6.1 The do-while Statement
-
The production do Statement while ( Expression ); is
evaluated as follows:
1. Let V = empty.
2.Evaluate Statement.
3.If Result(2). value is not empty, let V = Result(2). value.
4.If Result(2). type is continue and Result(2). target is in the current label set, go to step 7.
5. If Result(2). type is break and Result(2). target is in the current label set, return (normal, V,
empty).
6.If Result(2) is an abrupt completion, return Result(2).
7.Evaluate Expression.
8.Call GetValue(Result(7)).
9. Call ToBoolean(Result(8)).
10. If Result(9) is true, go to step 2.
11. Return (normal, V, empty);
- 12.6.2 The while statement
-
The production IterationStatement : while ( Expression ) Statement
is evaluated as follows:
1. Let V = empty.
2.Evaluate Expression.
3.Call GetValue(Result(2)).
4. Call ToBoolean(Result(3)).
5.If Result(4) is false, return (normal, V, empty).
6.Evaluate Statement.
7.If Result(6). value is not empty, let V = Result( 6). value.
8.If Result(6). type is continue and Result(6). target is in the current label set, go to 2.
9. If Result(6). type is break and Result(6). target is in the current label set, return (normal, V,
empty).
10. If Result(6) is an abrupt completion, return Result(6).
11. Go to step 2.
- 12.6.3 The for Statement
-
The production IterationStatement : for ( ExpressionNoInopt ;
Expressionopt ; Expressionopt) Statement is evaluated as follows:
1. If ExpressionNoIn is not present, go to step 4.
2. Evaluate ExpressionNoIn.
3. Call GetValue(Result(2)). (This value is not used.)
4. Let V = empty.
5. If the first Expression is not present, go to step 10.
6. Evaluate the first Expression.
7. Call GetValue(Result(6)).
8. Call ToBoolean(Result(7)).
9. If Result(8) is false, go to step 19.
10. Evaluate Statement.
11. If Result(10). value is not empty, let V = Result(10). value
12. If Result(10). type is break and Result(10). target is in the current label set, go to step 19.
13. If Result(10). type is continue and Result(10). target is in the current label set, go to step 15.
14. If Result(10) is an abrupt completion, return Result(10).
15. If the second Expression is not present, go to step 5.
16. Evaluate the second Expression.
17. Call GetValue(Result(16). (This value is not used.)
18. Go to step 5.
19. Return (normal, V, empty).
The production IterationStatement : for (var VariableDeclarationListNoIn ;
Expressionopt ; Expressionopt ) Statement is
evaluated as follows:
1. Evaluate VariableDeclarationListNoIn.
2. Let V = empty.
3. If the first Expression is not present, go to step 8.
4. Evaluate the first Expression.
5. Call GetValue(Result(4)).
6. Call ToBoolean(Result(5)).
7. If Result(6) is false, go to step 17.
8. Evaluate Statement.
9. If Result(8). value is not empty, let V = Result(8). value.
10. If Result(8). type is break and Result(8). target is in the current label set, go to step 17.
11. If Result(8). type is continue and Result(8). target is in the current label set, go to step 13.
12. If Result(8) is an abrupt completion, return Result(8).
13. If the second Expression is not present, go to step 3.
14. Evaluate the second Expression.
15. Call GetValue(Result(14)). (This value is not used.)
16. Go to step 3.
17. Return (normal, V, empty).
- 12.6.4 The for-in Statement
-
The production IterationStatement : for ( LeftHandSideExpression in
Expression ) Statement is evaluated as follows:
1. Evaluate the Expression.
2. Call GetValue(Result(1)).
3. Call ToObject(Result(2)).
4. Let V = empty.
5. Get the name of the next property of Result(3) that doesn't have the DontEnum attribute. If there is no such
property, go to step 14.
6. Evaluate the LeftHandSideExpression (it may be evaluated repeatedly).
7. Call PutValue(Result(6), Result(5)).
8. Evaluate Statement.
9. If Result(8). value is not empty, let V = Result(8). value.
10. If Result(8). type is break and Result(8). target is in the current label set, go to step 14.
11. If Result(8). type is continue and Result(8). target is in the current label set, go to step 5.
12. If Result(8) is an abrupt completion, return Result(8).
13. Go to step 5.
14. Return (normal, V, empty).
The production IterationStatement : for (var VariableDeclarationNoIn in
Expression ) Statement is evaluated as follows:
1. Evaluate VariableDeclarationNoIn.
2. Evaluate Expression.
3. Call GetValue(Result(2)).
4. Call ToObject(Result(3)).
5. Let V = empty.
6. Get the name of the next property of Result(4) that doesn't have the DontEnum attribute. If there is no such
property, go to step 15.
7. Evaluate Result(1) as if it were an Identifier; see 0 (yes, it may be evaluated repeatedly).
8. Call PutValue(Result(7), Result(6)).
9. Evaluate Statement.
10.If Result(9). value is not empty, let V = Result(9). value.
11.If Result(9). type is break and Result(9). target is in the current label set, go to step 15.
12.If Result(9). type is continue and Result(9). target is in the current label set, go to step 6.
13. If Result(8) is an abrupt completion, return Result(8).
14. Go to step 6.
15. Return (normal, V, empty).
The mechanics of enumerating the properties (step 5 in the first algorithm, step 6 in the second) is implementation
dependent. The order of enumeration is defined by the object. Properties of the object being enumerated may be deleted
during enumeration. If a property that has not yet been visited during enumeration is deleted, then it will not be
visited. If new properties are added to the object being enumerated during enumeration, the newly added properties are
not guaranteed to be visited in the active enumeration.
Enumerating the properties of an object includes enumerating properties of its prototype, and the prototype of the
prototype, and so on, recursively; but a property of a prototype is not enumerated if it is "shadowed" because some
previous object in the prototype chain has a property with the same name.
- 12.7 The continue Statement
-
Syntax
- ContinueStatement :
- continue [no LineTerminator here] Identifieropt ;
Semantics
A program is considered syntactically incorrect if either of the following are true:
- The program contains a continue statement without the optional Identifier, which is not
nested, directly or indirectly (but not crossing function boundaries), within an IterationStatement.
- The program contains a continue statement with the optional Identifier, where Identifier
does not appear in the label set of an enclosing (but not crossing function boundaries) IterationStatement.
A ContinueStatement without an Identifier is evaluated as follows:
1. Return (continue, empty, empty).
A ContinueStatement with the optional Identifier is evaluated as follows:
1. Return (continue, empty, Identifier).
- 12.8 The break Statement
-
Syntax
- BreakStatement :
- break [no LineTerminator here] Identifieropt ;
Semantics
A program is considered syntactically incorrect if either of the following are true:
- The program contains a break statement without the optional Identifier, which is not
nested, directly or indirectly (but not crossing function boundaries), within an IterationStatement or a
SwitchStatement.
- The program contains a break statement with the optional Identifier, where Identifier
does not appear in the label set of an enclosing (but not crossing function boundaries) Statement.
A BreakStatement without an Identifier is evaluated as follows:
1. Return (break, empty, empty).
A BreakStatement with an Identifier is evaluated as follows:
1. Return (break, empty, Identifier).
- 12.9 The return Statement
-
Syntax
- ReturnStatement :
- return [no LineTerminator here] Expressionopt ;
Semantics
An ECMAScript program is considered syntactically incorrect if it contains a return statement that is
not within a FunctionBody. Areturn statement causes a function to cease execution and return a value to the
caller. If Expression is omitted, the return value is undefined. Otherwise, the return value is the value
of Expression.
The production ReturnStatement : return [no LineTerminator here] Expressionopt
; is evaluated as:
1. If the Expression is not present, return (return, undefined, empty).
2. Evaluate Expression.
3. Call GetValue(Result(2)).
4. Return (return, Result(3), empty).
- 12.10 The with Statement
-
Syntax
- WithStatement :
- with ( Expression ) Statement
Description
The with statement adds a computed object to the front of the scope chain of the current execution
context, then executes a statement with this augmented scope chain, then restores the scope chain.
Semantics
The production WithStatement : with ( Expression ) Statement is
evaluated as follows:
1. Evaluate Expression.
2. Call GetValue(Result(1)).
3. Call ToObject(Result(2)).
4. Add Result(3) to the front of the scope chain.
5. Evaluate Statement using the augmented scope chain from step 4.
6. Let C be Result(5). If an exception was thrown in step 5, let C be (throw, V,
empty), where V is the exception. (Execution now proceeds as if no exception were thrown.)
7. Remove Result(3) from the front of the scope chain.
8. Return C.
NOTE
No matter how control leaves the embedded 'Statement', whether normally or by some form of abrupt completion or
exception, the scope chain is always restored to its former state.
- 12.11 The switch Statement
-
Syntax
- SwitchStatement :
- switch ( Expression ) CaseBlock
- CaseBlock :
- { CaseClausesopt }
{ CaseClausesopt DefaultClause CaseClausesopt }
- CaseClauses :
- CaseClause
CaseClauses CaseClause
- CaseClause :
- case Expression : StatementListopt
- DefaultClause :
- default : StatementListopt
Semantics
The production SwitchStatement : switch ( Expression ) CaseBlock
is evaluated as follows:
1. Evaluate Expression.
2. Call GetValue(Result(1)).
3. Evaluate CaseBlock, passing it Result(2) as a parameter.
4. If Result(3). type is break and Result(3). target is in the current label set, return (normal,
Result(3).value, empty).
5. Return Result(3).
The production CaseBlock : { CaseClausesopt }
is given an input parameter, input, and is evaluated as follows:
1. Let V = empty.
2. Let A be the list of CaseClause items in source text order.
3. Let C be the next CaseClause in A. If there is no such
CaseClause, then go to step 16.
4. Evaluate C.
5. If input is not equal to Result(4) as defined by the !== operator, then go to step 3.
6. If C does not have a StatementList, then go to step 10.
7. Evaluate C's StatementList and let R be the result.
8. If R is an abrupt completion, then return R.
9. Let V = R.value.
10. Let C be the next CaseClause in A. If there is no such
CaseClause, then go to step 16.
11. If C does not have a StatementList, then go to step 10.
12. Evaluate C's StatementList and let R be the result.
13. If R.value is not empty, then let V = R.value.
14. If R is an abrupt completion, then return (R.type, V, R.target).
15. Go to step 10.
16. Return (normal, V, empty).
The production CaseBlock : { CaseClausesopt DefaultClause CaseClausesopt } is
given an input parameter, input, and is evaluated as follows:
1. Let V = empty.
2. Let A be the list of CaseClause items in the first
CaseClauses, in source text order.
3. Let C be the next CaseClause in A. If there is no such
CaseClause, then go to step 11.
4. Evaluate C.
5. If input is not equal to Result(4) as defined by the !== operator, then go to step 3.
6. If C does not have a StatementList, then go to step 20.
7. Evaluate C's StatementList and let R be the result.
8. If R is an abrupt completion, then return R.
9. Let V = R.value.
10. Go to step 20.
11. Let B be the list of CaseClause items in the second
CaseClauses, in source text order.
12. Let C be the next CaseClause in B. If there is no such
CaseClause, then go to step 26.
13. Evaluate C.
14. If input is not equal to Result(13) as defined by the !== operator, then go to step 12.
15. If C does not have a StatementList, then go to step 31.
16. Evaluate C's StatementList and let R be the result.
17. If R is an abrupt completion, then return R.
18. Let V = R.value.
19. Go to step 31.
20. Let C be the next CaseClause in A. If there is no such
CaseClause, then go to step 26.
21. If C does not have a StatementList, then go to step 20.
22. Evaluate C's StatementList and let R be the result.
23. If R.value is not empty, then let V = R.value.
24. If R is an abrupt completion, then return (R.type, V, R.target).
25. Go to step 20.
26. If the DefaultClause does not have a StatementList,
then go to step 30.
27. Evaluate the DefaultClause's StatementList and let
R be the result.
28. If R.value is not empty, then let V = R.value.
29. If R is an abrupt completion, then return (R.type, V, R.target).
30. Let B be the list of CaseClause items in the second
CaseClauses, in source text order.
31. Let C be the next CaseClause in B. If there is no such
CaseClause, then go to step 37.
32. If C does not have a StatementList, then go to step 31.
33. Evaluate C's StatementList and let R be the result.
34. If R.value is not empty, then let V = R.value.
35. If R is an abrupt completion, then return (R.type, V, R.target).
36. Go to step 31.
37. Return (normal, V, empty).
The production CaseClause : case Expression : StatementListopt
is evaluated as follows:
1. Evaluate Expression.
2. Call GetValue(Result(1)).
3. Return Result(2).
NOTE
Evaluating CaseClause does not execute the associated StatementList. It simply evaluates the Expression and returns the
value, which the CaseBlock algorithm uses to determine which StatementList to start executing.
- 12.12 Labelled Statements
-
Syntax
- LabelledStatement :
- Identifier : Statement
Semantics
A Statement may be prefixed by a label. Labelled statements are only used in conjunction with labelled
break and continue statements. ECMAScript has no goto statement.
An ECMAScript program is considered syntactically incorrect if it contains a LabelledStatement that is
enclosed by a LabelledStatement with the same Identifier as label. This does not apply to labels appearing
within the body of a FunctionDeclaration that is nested, directly or indirectly, within a labelled statement.
The production Identifier : Statement is evaluated by adding Identifier to the label
set of Statement and then evaluating Statement. If theLabelledStatement itself has a non-empty label set,
these labels are also added to the label set of Statement before evaluating it. If the result of evaluating
Statement is (break, V, L) where L is equal to Identifier, the production results in (normal,
V, empty).
Prior to the evaluation of a LabelledStatement, the contained Statement is regarded as possessing an
empty label set, except if it is an IterationStatement or a SwitchStatement, in which case it is regarded
as possessing a label set consisting of the single element, empty.
- 12.13 The throw statement
-
Syntax
- ThrowStatement :
- throw [no LineTerminator here] Expression ;
Semantics
The production ThrowStatement : throw [no LineTerminator here]
Expression ; is evaluated as:
1. Evaluate Expression.
2. Call GetValue(Result(1)).
3. Return (throw, Result(2), empty).
- 12.14 The try statement
-
Syntax
- TryStatement :
- try Block Catch
try Block Finally
try Block Catch Finally
- Catch :
- catch (Identifier ) Block
- Finally :
- finally Block
Description
The try statement encloses a block of code in which an exceptional condition can occur, such as a
runtime error or a throw statement. The catch clause provides the exception-handling
code. When a catch clause catches an exception, its Identifier is bound to that exception.
Semantics
The production TryStatement : try Block Catch is evaluated as follows:
1. Evaluate Block.
2. If Result(1). type is not throw, return Result(1).
3. Evaluate Catch with parameter Result(1).
4. Return Result(3).
The production TryStatement : try Block Finally is evaluated as follows:
1. Evaluate Block.
2. Evaluate Finally.
3. If Result(2) .type is normal, return Result(1).
4. Return Result(2).
The production TryStatement : try Block Catch Finally is evaluated as follows:
1. Evaluate Block.
2. Let C = Result(1).
3. If Result(1). type is not throw, go to step 6.
4. Evaluate Catch with parameter Result(1).
5. Let C = Result(4).
6. Evaluate Finally.
7. If Result(6). type is normal, return C.
8. Return Result(6).
The production Catch : catch (Identifier ) Block is evaluated as follows:
1. Let C be the parameter that has been passed to this production.
2. Create a new object as if by the expression new Object().
3. Create a property in the object Result(2). The property's name is Identifier, valueisC. value, and
attributes are { DontDelete }.
4. Add Result(2) to the front of the scope chain.
5. Evaluate Block.
6. Remove Result(2) from the front of the scope chain.
7. Return Result(5).
The production Finally : finally Block is evaluated as follows:
1. Evaluate Block.
2. Return Result(1).