12 Statements
Syntax
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.
The result of evaluating a Statement is always a Completion value.
NOTE Several widely used implementations of ECMAScript are known to support the use of FunctionDeclaration as a Statement. However there are significant and irreconcilable variations among the implementations in the semantics applied to such FunctionDeclarations. Because of these irreconcilable differences, the use of a FunctionDeclaration as a Statement results in code that is not reliably portable among implementations. It is recommended that ECMAScript implementations either disallow this usage of FunctionDeclaration or issue a warning when such a usage is encountered. Future editions of ECMAScript may define alternative portable means for declaring functions in a Statement context.
12.1 Block
Syntax
{ StatementListopt }Semantics
The production Block : { } is evaluated as follows:
- Return (normal, empty, empty).
The production Block : { StatementList } is evaluated as follows:
- Return the result of evaluating StatementList.
The production StatementList : Statement is evaluated as follows:
- Let s be the result of evaluating Statement.
- If an exception was thrown, return (throw, V, empty) where V is the exception. (Execution now proceeds as if no exception were thrown.)
- Return s.
The production StatementList : StatementList Statement is evaluated as follows:
- Let sl be the result of evaluating StatementList.
- If sl is an abrupt completion, return sl.
- Let s be the result of evaluating Statement.
- If an exception was thrown, return (throw, V, empty) where V is the exception. (Execution now proceeds as if no exception were thrown.)
- If s.value is empty, let V = sl.value, otherwise let V = s.value.
- Return (s.type, V, s.target).
NOTE Steps 5 and 6 of the above algoritm ensure that the value of a StatementList is the value of the last value producing Statement in the StatementList. For example, the following calls to the eval function all return the value
1:
eval("1;;;;;")
eval("1;{}")
eval("1;var a;")
12.2 Variable Statement
Syntax
var VariableDeclarationList ;, VariableDeclaration, VariableDeclarationNoIn= AssignmentExpression= AssignmentExpressionNoInA variable statement declares variables that are created as defined in 10.5. 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:
- Evaluate VariableDeclarationList.
- Return (normal, empty, empty).
The production VariableDeclarationList :VariableDeclaration is evaluated as follows:
- Evaluate VariableDeclaration.
The production VariableDeclarationList : VariableDeclarationList , VariableDeclaration is
evaluated as follows:
- Evaluate VariableDeclarationList.
- Evaluate VariableDeclaration.
The production VariableDeclaration : Identifier is evaluated as follows:
- Return a String value containing the same sequence of characters as in the Identifier.
The production VariableDeclaration : Identifier Initialiser is evaluated as follows:
- Let lhs be the result of evaluating Identifier as described in 11.1.2.
- Let rhs be the result of evaluating Initialiser.
- Let value be GetValue(rhs).
- Call PutValue(lhs, value).
- Return a String value containing the same sequence of characters as in the Identifier.
NOTE The String value of a VariableDeclaration is used in the evaluation of for-in statements (12.6.4).
If a VariableDeclaration is nested within a with statement and the Identifier in the VariableDeclaration is the same as a property name of the binding object of the with statement’s object environment record, then step 4 will assign value to the property instead of to the VariableEnvironment binding of the Identifier.
The production Initialiser : =
AssignmentExpression is evaluated as follows:
- Return the result of evaluating AssignmentExpression.
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.2.1 Strict Mode Restrictions
It is a SyntaxError if a VariableDeclaration or VariableDeclarationNoIn occurs within strict code and its Identifier is either "eval" or "arguments".
12.3 Empty Statement
Syntax
;Semantics
The production EmptyStatement : ; is evaluated as follows:
- Return (normal, empty, empty).
12.4 Expression Statement
Syntax
{, function}] Expression ;NOTE 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:
- Let exprRef be the result of evaluating Expression.
- Return (normal, GetValue(exprRef), empty).
12.5 The if Statement
Syntax
if ( Expression ) Statement else Statementif ( Expression ) StatementEach 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:
- Let exprRef be the result of evaluating Expression.
- If ToBoolean(GetValue(exprRef)) is true, then
- Return the result of evaluating the first Statement.
- Else,
- Return the result of evaluating the second Statement.
The production IfStatement : if
( Expression ) Statement
is evaluated as follows:
12.6 Iteration Statements
Syntax
do Statement while ( Expression );while ( Expression ) Statementfor ( ExpressionNoInopt ; Expressionopt ; Expressionopt ) Statementfor ( var VariableDeclarationListNoIn ; Expressionopt ; Expressionopt ) Statementfor ( LeftHandSideExpression in Expression ) Statementfor ( var VariableDeclarationNoIn in Expression ) Statement12.6.1 The do-while Statement
The production do Statement while ( Expression ); is evaluated as follows:
- Let V = empty.
- Let iterating be true.
- Repeat, while iterating is true
- Let stmt be the result of evaluating Statement.
- If stmt.value is not empty, let V = stmt.value.
- If stmt.type is not continue || stmt.target is not in
the current label set, then
- If stmt.type is break and stmt.target is in the current label set, return (normal, V, empty).
- If stmt is an abrupt completion, return stmt.
- Let exprRef be the result of evaluating Expression.
- If ToBoolean(GetValue(exprRef)) is false, set iterating to false.
- Return (normal, V, empty);
12.6.2 The while Statement
The production IterationStatement : while ( Expression ) Statement is evaluated as follows:
- Let V = empty.
- Repeat
- Let exprRef be the result of evaluating Expression.
- If ToBoolean(GetValue(exprRef)) is false, return (normal, V, empty).
- Let stmt be the result of evaluating Statement.
- If stmt.value is not empty, let V = stmt.value.
- If stmt.type is not continue || stmt.target is not in
the current label set, then
- If stmt.type is break and stmt.target is in the
current label set, then
- Return (normal, V, empty).
- If stmt is an abrupt completion, return stmt.
- If stmt.type is break and stmt.target is in the
current label set, then
12.6.3 The for Statement
The production
IterationStatement : for ( ExpressionNoInopt ;
Expressionopt ; Expressionopt
) Statement
is evaluated as follows:
- If ExpressionNoIn is present, then.
- Let exprRef be the result of evaluating ExpressionNoIn.
- Call GetValue(exprRef). (This value is not used but the call may have side-effects.)
- Let V = empty.
- Repeat
- If the first Expression is present, then
- Let stmt be the result of evaluating Statement.
- If stmt.value is not empty, let V = stmt.value
- If stmt.type is break and stmt.target is in the current label set, return (normal, V, empty).
- If stmt.type is not continue || stmt.target is not in
the current label set, then
- If stmt is an abrupt completion, return stmt.
- If the second Expression is present, then
- Let incExprRef be the result of evaluating the second Expression.
- Call GetValue(incExprRef). (This value is not used.)
The production
IterationStatement : for ( var VariableDeclarationListNoIn
; Expressionopt ; Expressionopt ) Statement
is evaluated
as follows:
- Evaluate VariableDeclarationListNoIn.
- Let V = empty.
- Repeat
- If the first Expression is present, then
- Let stmt be the result of evaluating Statement.
- If stmt.value is not empty, let V = stmt.value.
- If stmt.type is break and stmt.target is in the current label set, return (normal, V, empty).
- If stmt.type is not continue || stmt.target is not in
the current label set, then
- If stmt is an abrupt completion, return stmt.
- If the second Expression is present, then.
- Let incExprRef be the result of evaluating the second Expression.
- Call GetValue(incExprRef). (This value is not used.)
12.6.4 The for-in Statement
The production IterationStatement : for ( LeftHandSideExpression in Expression ) Statement is evaluated as follows:
- Let exprRef be the result of evaluating the Expression.
- Let experValue be GetValue(exprRef).
- If experValue is null or undefined, return (normal, empty, empty).
- Let obj be ToObject(experValue).
- Let V = empty.
- Repeat
- Let P be the name of the next property of obj whose [[Enumerable]] attribute is true. If there is no such property, return (normal, V, empty).
- Let lhsRef be the result of evaluating the LeftHandSideExpression ( it may be evaluated repeatedly).
- Call PutValue(lhsRef, P).
- Let stmt be the result of evaluating Statement.
- If stmt.value is not empty, let V = stmt.value.
- If stmt.type is break and stmt.target is in the current label set, return (normal, V, empty).
- If stmt.type is not continue || stmt.target is not in the current label set, then
- If stmt is an abrupt completion, return stmt.
The production
IterationStatement : for ( var VariableDeclarationNoIn
in Expression ) Statement
is evaluated as follows:
- Let varName be the result of evaluating VariableDeclarationNoIn.
- Let exprRef be the result of evaluating the Expression.
- Let experValue be GetValue(exprRef).
- If experValue is null or undefined, return (normal, empty, empty).
- Let obj be ToObject(experValue).
- Let V = empty.
- Repeat
- Let P be the name of the next property of obj whose [[Enumerable]] attribute is true. If there is no such property, return (normal, V, empty).
- Let varRef be the result of evaluating varName as if it were an Identifier Reference (11.1.2); it may be evaluated repeatedly.
- Call PutValue(varRef, P).
- Let stmt be the result of evaluating Statement.
- If stmt.value is not empty, let V = stmt.value.
- If stmt.type is break and stmt.target is in the current label set, return (normal, V, empty).
- If stmt.type is not continue || stmt.target is not in
the current label set, then
- If stmt is an abrupt completion, return stmt.
The mechanics and order of enumerating the properties (step 6.a in the first algorithm, step 7.a in the second) is not specified. 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. A property name must not be visited more than once in any 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. The values of [[Enumerable]] attributes are not considered when determining if a property of a prototype object is shadowed by a previous object on the prototype chain.
NOTE See NOTE 11.13.1.
12.7 The continue Statement
Syntax
continue ;continue [no LineTerminator here] Identifier ;Semantics
A program is considered syntactically incorrect if either of the following is true:
-
The program contains a
continuestatement without the optional Identifier, which is not nested, directly or indirectly (but not crossing function boundaries), within an IterationStatement. -
The program contains a
continuestatement 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:
- Return (continue, empty, empty).
A ContinueStatement with the optional Identifier is evaluated as follows:
- Return (continue, empty, Identifier).
12.8 The break Statement
Syntax
break ;break [no LineTerminator here] Identifier ;Semantics
A program is considered syntactically incorrect if either of the following is true:
-
The program contains a
breakstatement 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
breakstatement 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:
- Return (break, empty, empty).
A BreakStatement with an Identifier is evaluated as follows:
- Return (break, empty, Identifier).
12.9 The return Statement
Syntax
return ;return [no LineTerminator here] Expression ;Semantics
An ECMAScript program is considered syntactically incorrect if it contains a return statement that is not
within a FunctionBody. A return 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.
A ReturnStatement is evaluated as follows:
- If the Expression is not present, return (return, undefined, empty).
- Let exprRef be the result of evaluating Expression.
- Return (return, GetValue(exprRef), empty).
12.10 The with Statement
Syntax
with ( Expression ) StatementThe with statement adds an object environment record for a computed object to the lexical environment of the current execution context. It then executes a statement using this augmented
lexical environment. Finally, it restores the original lexical
environment.
Semantics
The production WithStatement : with ( Expression ) Statement is evaluated as follows:
- Let val be the result of evaluating Expression.
- Let obj be ToObject(GetValue(val)).
- Let oldEnv be the running execution context’s LexicalEnvironment.
- Let newEnv be the result of calling NewObjectEnvironment passing obj and oldEnv as the arguments.
- Set the provideThis flag of newEnv to true.
- Set the running execution context’s LexicalEnvironment to newEnv.
- Let C be the result of evaluating Statement but if an exception is thrown during the evaluation, let C be (throw, V, empty), where V is the exception. (Execution now proceeds as if no exception were thrown.)
- Set the running execution context’s Lexical Environment to oldEnv.
- Return C.
NOTE No matter how control leaves the embedded Statement, whether normally or by some form of abrupt completion or exception, the LexicalEnvironment is always restored to its former state.
12.10.1 Strict Mode Restrictions
Strict mode code may not include a WithStatement. The occurrence of a WithStatement in such a context is treated as a SyntaxError.
12.11 The switch Statement
Syntax
switch ( Expression ) CaseBlock{ CaseClausesopt }{ CaseClausesopt DefaultClause CaseClausesopt }case Expression : StatementListoptdefault : StatementListoptSemantics
The production SwitchStatement : switch ( Expression ) CaseBlock is evaluated as follows:
- Let exprRef be the result of evaluating Expression.
- Let R be the result of evaluating CaseBlock, passing it GetValue(exprRef) as a parameter.
- If R.type is break and R.target is in the current label set, return (normal, R.value, empty).
- Return R.
The production CaseBlock : {
CaseClausesopt } is given an input parameter,
input, and is evaluated as follows:
- Let V = empty.
- Let A be the list of CaseClause items in source text order.
- Let searching be true.
- Repeat, while searching is true
- Let C be the next CaseClause in A. If there is no such CaseClause, return (normal, V, empty).
- Let clauseSelector be the result of evaluating C.
- If input is equal to clauseSelector as defined by the ===
operator, then
- Set searching to false.
- If C has a StatementList, then
- Evaluate C’s StatementList and let R be the result.
- If R is an abrupt completion, then return R.
- Let V = R.value.
- Repeat
- Let C be the next CaseClause in A. If there is no such CaseClause, return (normal, V, empty).
- If C has a StatementList, then
- Evaluate C’s StatementList and let R be the result.
- If R.value is not empty, then let V = R.value.
- If R is an abrupt completion, then return (R.type, V, R.target).
The production CaseBlock : {
CaseClausesopt DefaultClause CaseClausesopt } is given an input parameter, input, and
is evaluated as follows:
- Let V = empty.
- Let A be the list of CaseClause items in the first CaseClauses, in source text order.
- Let B be the list of CaseClause items in the second CaseClauses, in source text order.
- Let found be false.
- Repeat letting C be in order each CaseClause in A
- If found is false, then
- Let clauseSelector be the result of evaluating C.
- If input is equal to clauseSelector as defined by the === operator, then set found to true.
- If found is true, then
- If C has a StatementList, then
- Evaluate C’s StatementList and let R be the result.
- If R.value is not empty, then let V = R.value.
- R is an abrupt completion, then return (R.type, V, R.target).
- If C has a StatementList, then
- If found is false, then
- Let foundInB be false.
- If found is false, then
- Repeat, while foundInB is false and all elements of B have not been processed
- Let C be the next CaseClause in B.
- Let clauseSelector be the result of evaluating C.
- If input is equal to clauseSelector as defined by the === operator, then
- Set foundInB to true.
- If C has a StatementList, then
- Evaluate C’s StatementList and let R be the result.
- If R.value is not empty, then let V = R.value.
- R is an abrupt completion, then return (R.type, V, R.target).
- Repeat, while foundInB is false and all elements of B have not been processed
- If foundInB is false and the DefaultClause has a StatementList, then
- Evaluate the DefaultClause’s StatementList and let R be the result.
- If R.value is not empty, then let V = R.value.
- If R is an abrupt completion, then return (R.type, V, R.target).
- Repeat (Note that if step 7.a.i has been performed this loop does not start at the beginning of B)
- Let C be the next CaseClause in B. If there is no such CaseClause, return (normal, V, empty).
- If C has a StatementList, then
- Evaluate C’s StatementList and let R be the result.
- If R.value is not empty, then let V = R.value.
- If R is an abrupt completion, then return (R.type, V, R.target).
The production CaseClause : case
Expression : StatementListopt is
evaluated as follows:
- Let exprRef be the result of evaluating Expression.
- Return GetValue(exprRef).
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
: StatementSemantics
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 the LabelledStatement 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, unless 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
throw [no LineTerminator here] Expression ;Semantics
The production ThrowStatement : throw [no LineTerminator here] Expression ; is evaluated as follows:
- Let exprRef be the result of evaluating Expression.
- Return (throw, GetValue(exprRef), empty).
12.14 The try Statement
Syntax
try Block Catchtry Block Finallytry Block Catch Finallycatch ( Identifier ) Blockfinally BlockThe 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:
- Let B be the result of evaluating Block.
- If B.type is not throw, return B.
- Return the result of evaluating Catch with parameter B.value.
The production TryStatement : try Block Finally is evaluated as follows:
- Let B be the result of evaluating Block.
- Let F be the result of evaluating Finally.
- If F.type is normal, return B.
- Return F.
The production TryStatement : try Block Catch Finally is
evaluated as follows:
- Let B be the result of evaluating Block.
- If B.type is throw, then
- Let C be the result of evaluating Catch with parameter B.value.
- Else, B.type is not throw,
- Let C be B.
- Let F be the result of evaluating Finally.
- If F.type is normal, return C.
- Return F.
The production Catch : catch
( Identifier ) Block is
evaluated as follows:
- Let C be the parameter that has been passed to this production.
- Let oldEnv be the running execution context’s LexicalEnvironment.
- Let catchEnv be the result of calling NewDeclarativeEnvironment passing oldEnv as the argument.
- Call the CreateMutableBinding concrete method of catchEnv passing the Identifier String value as the argument.
- Call the SetMutableBinding concrete method of catchEnv passing the Identifier, C, and false as arguments. Note that the last argument is immaterial in this situation.
- Set the running execution context’s LexicalEnvironment to catchEnv.
- Let B be the result of evaluating Block.
- Set the running execution context’s LexicalEnvironment to oldEnv.
- Return B.
NOTE No matter how control leaves the Block the LexicalEnvironment is always restored to its former state.
The production Finally : finally
Block is evaluated as follows:
- Return the result of evaluating Block.
12.14.1 Strict Mode Restrictions
It is a SyntaxError if a TryStatement with a Catch occurs within
strict code and the Identifier of the Catch
production is either "eval" or "arguments".
12.15 The debugger statement
Syntax
debugger ;Semantics
Evaluating the DebuggerStatement production may allow an implementation to cause a breakpoint when run under a debugger. If a debugger is not present or active this statement has no observable effect.
The production DebuggerStatement : debugger ; is evaluated as follows:
- If an implementation defined debugging facility is available and enabled, then
- Perform an implementation defined debugging action.
- Let result be an implementation defined Completion value.
- Else
- Let result be (normal, empty, empty).
- Return result.