15 ECMAScript Language: Functions and Classes

Note

Various ECMAScript language elements cause the creation of ECMAScript function objects (10.2). Evaluation of such functions starts with the execution of their [[Call]] internal method (10.2.1).

15.1 Parameter Lists

Syntax

UniqueFormalParameters[Yield, Await] : FormalParameters[?Yield, ?Await] FormalParameters[Yield, Await] : [empty] FunctionRestParameter[?Yield, ?Await] FormalParameterList[?Yield, ?Await] FormalParameterList[?Yield, ?Await] , FormalParameterList[?Yield, ?Await] , FunctionRestParameter[?Yield, ?Await] FormalParameterList[Yield, Await] : FormalParameter[?Yield, ?Await] FormalParameterList[?Yield, ?Await] , FormalParameter[?Yield, ?Await] FunctionRestParameter[Yield, Await] : BindingRestElement[?Yield, ?Await] FormalParameter[Yield, Await] : BindingElement[?Yield, ?Await]

15.1.1 Static Semantics: Early Errors

UniqueFormalParameters : FormalParameters FormalParameters : FormalParameterList Note

Multiple occurrences of the same BindingIdentifier in a FormalParameterList is only allowed for functions which have simple parameter lists and which are not defined in strict mode code.

15.1.2 Static Semantics: ContainsExpression

ObjectBindingPattern : { } { BindingRestProperty }
  1. Return false.
ObjectBindingPattern : { BindingPropertyList , BindingRestProperty }
  1. Return ContainsExpression of BindingPropertyList.
ArrayBindingPattern : [ Elisionopt ]
  1. Return false.
ArrayBindingPattern : [ Elisionopt BindingRestElement ]
  1. Return ContainsExpression of BindingRestElement.
ArrayBindingPattern : [ BindingElementList , Elisionopt ]
  1. Return ContainsExpression of BindingElementList.
ArrayBindingPattern : [ BindingElementList , Elisionopt BindingRestElement ]
  1. Let has be ContainsExpression of BindingElementList.
  2. If has is true, return true.
  3. Return ContainsExpression of BindingRestElement.
BindingPropertyList : BindingPropertyList , BindingProperty
  1. Let has be ContainsExpression of BindingPropertyList.
  2. If has is true, return true.
  3. Return ContainsExpression of BindingProperty.
BindingElementList : BindingElementList , BindingElisionElement
  1. Let has be ContainsExpression of BindingElementList.
  2. If has is true, return true.
  3. Return ContainsExpression of BindingElisionElement.
BindingElisionElement : Elisionopt BindingElement
  1. Return ContainsExpression of BindingElement.
BindingProperty : PropertyName : BindingElement
  1. Let has be IsComputedPropertyKey of PropertyName.
  2. If has is true, return true.
  3. Return ContainsExpression of BindingElement.
BindingElement : BindingPattern Initializer
  1. Return true.
SingleNameBinding : BindingIdentifier
  1. Return false.
SingleNameBinding : BindingIdentifier Initializer
  1. Return true.
BindingRestElement : ... BindingIdentifier
  1. Return false.
BindingRestElement : ... BindingPattern
  1. Return ContainsExpression of BindingPattern.
FormalParameters : [empty]
  1. Return false.
FormalParameters : FormalParameterList , FunctionRestParameter
  1. If ContainsExpression of FormalParameterList is true, return true.
  2. Return ContainsExpression of FunctionRestParameter.
FormalParameterList : FormalParameterList , FormalParameter
  1. If ContainsExpression of FormalParameterList is true, return true.
  2. Return ContainsExpression of FormalParameter.
ArrowParameters : BindingIdentifier
  1. Return false.
ArrowParameters : CoverParenthesizedExpressionAndArrowParameterList
  1. Let formals be the ArrowFormalParameters that is covered by CoverParenthesizedExpressionAndArrowParameterList.
  2. Return ContainsExpression of formals.
AsyncArrowBindingIdentifier : BindingIdentifier
  1. Return false.

15.1.3 Static Semantics: IsSimpleParameterList

BindingElement : BindingPattern
  1. Return false.
BindingElement : BindingPattern Initializer
  1. Return false.
SingleNameBinding : BindingIdentifier
  1. Return true.
SingleNameBinding : BindingIdentifier Initializer
  1. Return false.
FormalParameters : [empty]
  1. Return true.
FormalParameters : FunctionRestParameter
  1. Return false.
FormalParameters : FormalParameterList , FunctionRestParameter
  1. Return false.
FormalParameterList : FormalParameterList , FormalParameter
  1. If IsSimpleParameterList of FormalParameterList is false, return false.
  2. Return IsSimpleParameterList of FormalParameter.
FormalParameter : BindingElement
  1. Return IsSimpleParameterList of BindingElement.
ArrowParameters : BindingIdentifier
  1. Return true.
ArrowParameters : CoverParenthesizedExpressionAndArrowParameterList
  1. Let formals be the ArrowFormalParameters that is covered by CoverParenthesizedExpressionAndArrowParameterList.
  2. Return IsSimpleParameterList of formals.
AsyncArrowBindingIdentifier : BindingIdentifier
  1. Return true.
CoverCallExpressionAndAsyncArrowHead : MemberExpression Arguments
  1. Let head be the AsyncArrowHead that is covered by CoverCallExpressionAndAsyncArrowHead.
  2. Return IsSimpleParameterList of head.

15.1.4 Static Semantics: HasInitializer

BindingElement : BindingPattern
  1. Return false.
BindingElement : BindingPattern Initializer
  1. Return true.
SingleNameBinding : BindingIdentifier
  1. Return false.
SingleNameBinding : BindingIdentifier Initializer
  1. Return true.
FormalParameterList : FormalParameterList , FormalParameter
  1. If HasInitializer of FormalParameterList is true, return true.
  2. Return HasInitializer of FormalParameter.

15.1.5 Static Semantics: ExpectedArgumentCount

FormalParameters : [empty] FunctionRestParameter
  1. Return 0.
FormalParameters : FormalParameterList , FunctionRestParameter
  1. Return ExpectedArgumentCount of FormalParameterList.
Note

The ExpectedArgumentCount of a FormalParameterList is the number of FormalParameters to the left of either the rest parameter or the first FormalParameter with an Initializer. A FormalParameter without an initializer is allowed after the first parameter with an initializer but such parameters are considered to be optional with undefined as their default value.

FormalParameterList : FormalParameter
  1. If HasInitializer of FormalParameter is true, return 0.
  2. Return 1.
FormalParameterList : FormalParameterList , FormalParameter
  1. Let count be ExpectedArgumentCount of FormalParameterList.
  2. If HasInitializer of FormalParameterList is true or HasInitializer of FormalParameter is true, return count.
  3. Return count + 1.
ArrowParameters : BindingIdentifier
  1. Return 1.
ArrowParameters : CoverParenthesizedExpressionAndArrowParameterList
  1. Let formals be the ArrowFormalParameters that is covered by CoverParenthesizedExpressionAndArrowParameterList.
  2. Return ExpectedArgumentCount of formals.
PropertySetParameterList : FormalParameter
  1. If HasInitializer of FormalParameter is true, return 0.
  2. Return 1.
AsyncArrowBindingIdentifier : BindingIdentifier
  1. Return 1.

15.2 Function Definitions

Syntax

FunctionDeclaration[Yield, Await, Default] : function BindingIdentifier[?Yield, ?Await] ( FormalParameters[~Yield, ~Await] ) { FunctionBody[~Yield, ~Await] } [+Default] function ( FormalParameters[~Yield, ~Await] ) { FunctionBody[~Yield, ~Await] } FunctionExpression : function BindingIdentifier[~Yield, ~Await]opt ( FormalParameters[~Yield, ~Await] ) { FunctionBody[~Yield, ~Await] } FunctionBody[Yield, Await] : FunctionStatementList[?Yield, ?Await] FunctionStatementList[Yield, Await] : StatementList[?Yield, ?Await, +Return]opt

15.2.1 Static Semantics: Early Errors

FunctionDeclaration : function BindingIdentifier ( FormalParameters ) { FunctionBody } function ( FormalParameters ) { FunctionBody } FunctionExpression : function BindingIdentifieropt ( FormalParameters ) { FunctionBody } Note

The LexicallyDeclaredNames of a FunctionBody does not include identifiers bound using var or function declarations.

FunctionBody : FunctionStatementList

15.2.2 Static Semantics: FunctionBodyContainsUseStrict

FunctionBody : FunctionStatementList
  1. If the Directive Prologue of FunctionBody contains a Use Strict Directive, return true; otherwise, return false.

15.2.3 Runtime Semantics: EvaluateFunctionBody

With parameters functionObject and argumentsList (a List).

FunctionBody : FunctionStatementList
  1. Perform ? FunctionDeclarationInstantiation(functionObject, argumentsList).
  2. Return the result of evaluating FunctionStatementList.

15.2.4 Runtime Semantics: InstantiateOrdinaryFunctionObject

With parameters scope and privateScope.

FunctionDeclaration : function BindingIdentifier ( FormalParameters ) { FunctionBody }
  1. Let name be StringValue of BindingIdentifier.
  2. Let sourceText be the source text matched by FunctionDeclaration.
  3. Let F be OrdinaryFunctionCreate(%Function.prototype%, sourceText, FormalParameters, FunctionBody, non-lexical-this, scope, privateScope).
  4. Perform SetFunctionName(F, name).
  5. Perform MakeConstructor(F).
  6. Return F.
FunctionDeclaration : function ( FormalParameters ) { FunctionBody }
  1. Let sourceText be the source text matched by FunctionDeclaration.
  2. Let F be OrdinaryFunctionCreate(%Function.prototype%, sourceText, FormalParameters, FunctionBody, non-lexical-this, scope, privateScope).
  3. Perform SetFunctionName(F, "default").
  4. Perform MakeConstructor(F).
  5. Return F.
Note

An anonymous FunctionDeclaration can only occur as part of an export default declaration, and its function code is therefore always strict mode code.

15.2.5 Runtime Semantics: InstantiateOrdinaryFunctionExpression

With optional parameter name.

FunctionExpression : function ( FormalParameters ) { FunctionBody }
  1. If name is not present, set name to "".
  2. Let scope be the LexicalEnvironment of the running execution context.
  3. Let privateScope be the running execution context's PrivateEnvironment.
  4. Let sourceText be the source text matched by FunctionExpression.
  5. Let closure be OrdinaryFunctionCreate(%Function.prototype%, sourceText, FormalParameters, FunctionBody, non-lexical-this, scope, privateScope).
  6. Perform SetFunctionName(closure, name).
  7. Perform MakeConstructor(closure).
  8. Return closure.
FunctionExpression : function BindingIdentifier ( FormalParameters ) { FunctionBody }
  1. Assert: name is not present.
  2. Set name to StringValue of BindingIdentifier.
  3. Let scope be the running execution context's LexicalEnvironment.
  4. Let funcEnv be NewDeclarativeEnvironment(scope).
  5. Perform funcEnv.CreateImmutableBinding(name, false).
  6. Let privateScope be the running execution context's PrivateEnvironment.
  7. Let sourceText be the source text matched by FunctionExpression.
  8. Let closure be OrdinaryFunctionCreate(%Function.prototype%, sourceText, FormalParameters, FunctionBody, non-lexical-this, funcEnv, privateScope).
  9. Perform SetFunctionName(closure, name).
  10. Perform MakeConstructor(closure).
  11. Perform funcEnv.InitializeBinding(name, closure).
  12. Return closure.
Note

The BindingIdentifier in a FunctionExpression can be referenced from inside the FunctionExpression's FunctionBody to allow the function to call itself recursively. However, unlike in a FunctionDeclaration, the BindingIdentifier in a FunctionExpression cannot be referenced from and does not affect the scope enclosing the FunctionExpression.

15.2.6 Runtime Semantics: Evaluation

FunctionDeclaration : function BindingIdentifier ( FormalParameters ) { FunctionBody }
  1. Return NormalCompletion(empty).
Note 1

An alternative semantics is provided in B.3.2.

FunctionDeclaration : function ( FormalParameters ) { FunctionBody }
  1. Return NormalCompletion(empty).
FunctionExpression : function BindingIdentifieropt ( FormalParameters ) { FunctionBody }
  1. Return InstantiateOrdinaryFunctionExpression of FunctionExpression.
Note 2

A "prototype" property is automatically created for every function defined using a FunctionDeclaration or FunctionExpression, to allow for the possibility that the function will be used as a constructor.

FunctionStatementList : [empty]
  1. Return NormalCompletion(undefined).

15.3 Arrow Function Definitions

Syntax

ArrowFunction[In, Yield, Await] : ArrowParameters[?Yield, ?Await] [no LineTerminator here] => ConciseBody[?In] ArrowParameters[Yield, Await] : BindingIdentifier[?Yield, ?Await] CoverParenthesizedExpressionAndArrowParameterList[?Yield, ?Await] ConciseBody[In] : [lookahead ≠ {] ExpressionBody[?In, ~Await] { FunctionBody[~Yield, ~Await] } ExpressionBody[In, Await] : AssignmentExpression[?In, ~Yield, ?Await]

Supplemental Syntax

When processing an instance of the production
ArrowParameters[Yield, Await] : CoverParenthesizedExpressionAndArrowParameterList[?Yield, ?Await]
the interpretation of CoverParenthesizedExpressionAndArrowParameterList is refined using the following grammar:

ArrowFormalParameters[Yield, Await] : ( UniqueFormalParameters[?Yield, ?Await] )

15.3.1 Static Semantics: Early Errors

ArrowFunction : ArrowParameters => ConciseBody ArrowParameters : CoverParenthesizedExpressionAndArrowParameterList

15.3.2 Static Semantics: ConciseBodyContainsUseStrict

ConciseBody : ExpressionBody
  1. Return false.
ConciseBody : { FunctionBody }
  1. Return FunctionBodyContainsUseStrict of FunctionBody.

15.3.3 Runtime Semantics: EvaluateConciseBody

With parameters functionObject and argumentsList (a List).

ConciseBody : ExpressionBody
  1. Perform ? FunctionDeclarationInstantiation(functionObject, argumentsList).
  2. Return the result of evaluating ExpressionBody.

15.3.4 Runtime Semantics: InstantiateArrowFunctionExpression

With optional parameter name.

ArrowFunction : ArrowParameters => ConciseBody
  1. If name is not present, set name to "".
  2. Let scope be the LexicalEnvironment of the running execution context.
  3. Let privateScope be the running execution context's PrivateEnvironment.
  4. Let sourceText be the source text matched by ArrowFunction.
  5. Let closure be OrdinaryFunctionCreate(%Function.prototype%, sourceText, ArrowParameters, ConciseBody, lexical-this, scope, privateScope).
  6. Perform SetFunctionName(closure, name).
  7. Return closure.
Note

An ArrowFunction does not define local bindings for arguments, super, this, or new.target. Any reference to arguments, super, this, or new.target within an ArrowFunction must resolve to a binding in a lexically enclosing environment. Typically this will be the Function Environment of an immediately enclosing function. Even though an ArrowFunction may contain references to super, the function object created in step 5 is not made into a method by performing MakeMethod. An ArrowFunction that references super is always contained within a non-ArrowFunction and the necessary state to implement super is accessible via the scope that is captured by the function object of the ArrowFunction.

15.3.5 Runtime Semantics: Evaluation

ArrowFunction : ArrowParameters => ConciseBody
  1. Return InstantiateArrowFunctionExpression of ArrowFunction.
ExpressionBody : AssignmentExpression
  1. Let exprRef be the result of evaluating AssignmentExpression.
  2. Let exprValue be ? GetValue(exprRef).
  3. Return Completion { [[Type]]: return, [[Value]]: exprValue, [[Target]]: empty }.

15.4 Method Definitions

Syntax

MethodDefinition[Yield, Await] : ClassElementName[?Yield, ?Await] ( UniqueFormalParameters[~Yield, ~Await] ) { FunctionBody[~Yield, ~Await] } GeneratorMethod[?Yield, ?Await] AsyncMethod[?Yield, ?Await] AsyncGeneratorMethod[?Yield, ?Await] get ClassElementName[?Yield, ?Await] ( ) { FunctionBody[~Yield, ~Await] } set ClassElementName[?Yield, ?Await] ( PropertySetParameterList ) { FunctionBody[~Yield, ~Await] } PropertySetParameterList : FormalParameter[~Yield, ~Await]

15.4.1 Static Semantics: Early Errors

MethodDefinition : ClassElementName ( UniqueFormalParameters ) { FunctionBody } MethodDefinition : set ClassElementName ( PropertySetParameterList ) { FunctionBody }

15.4.2 Static Semantics: HasDirectSuper

MethodDefinition : ClassElementName ( UniqueFormalParameters ) { FunctionBody }
  1. If UniqueFormalParameters Contains SuperCall is true, return true.
  2. Return FunctionBody Contains SuperCall.
MethodDefinition : get ClassElementName ( ) { FunctionBody }
  1. Return FunctionBody Contains SuperCall.
MethodDefinition : set ClassElementName ( PropertySetParameterList ) { FunctionBody }
  1. If PropertySetParameterList Contains SuperCall is true, return true.
  2. Return FunctionBody Contains SuperCall.
GeneratorMethod : * ClassElementName ( UniqueFormalParameters ) { GeneratorBody }
  1. If UniqueFormalParameters Contains SuperCall is true, return true.
  2. Return GeneratorBody Contains SuperCall.
AsyncGeneratorMethod : async * ClassElementName ( UniqueFormalParameters ) { AsyncGeneratorBody }
  1. If UniqueFormalParameters Contains SuperCall is true, return true.
  2. Return AsyncGeneratorBody Contains SuperCall.
AsyncMethod : async ClassElementName ( UniqueFormalParameters ) { AsyncFunctionBody }
  1. If UniqueFormalParameters Contains SuperCall is true, return true.
  2. Return AsyncFunctionBody Contains SuperCall.

15.4.3 Static Semantics: SpecialMethod

MethodDefinition : ClassElementName ( UniqueFormalParameters ) { FunctionBody }
  1. Return false.
MethodDefinition : GeneratorMethod AsyncMethod AsyncGeneratorMethod get ClassElementName ( ) { FunctionBody } set ClassElementName ( PropertySetParameterList ) { FunctionBody }
  1. Return true.

15.4.4 Runtime Semantics: DefineMethod

With parameter object and optional parameter functionPrototype.

MethodDefinition : ClassElementName ( UniqueFormalParameters ) { FunctionBody }
  1. Let propKey be the result of evaluating ClassElementName.
  2. ReturnIfAbrupt(propKey).
  3. Let scope be the running execution context's LexicalEnvironment.
  4. Let privateScope be the running execution context's PrivateEnvironment.
  5. If functionPrototype is present, then
    1. Let prototype be functionPrototype.
  6. Else,
    1. Let prototype be %Function.prototype%.
  7. Let sourceText be the source text matched by MethodDefinition.
  8. Let closure be OrdinaryFunctionCreate(prototype, sourceText, UniqueFormalParameters, FunctionBody, non-lexical-this, scope, privateScope).
  9. Perform MakeMethod(closure, object).
  10. Return the Record { [[Key]]: propKey, [[Closure]]: closure }.

15.4.5 Runtime Semantics: MethodDefinitionEvaluation

With parameters object and enumerable.

MethodDefinition : ClassElementName ( UniqueFormalParameters ) { FunctionBody }
  1. Let methodDef be ? DefineMethod of MethodDefinition with argument object.
  2. Perform ! SetFunctionName(methodDef.[[Closure]], methodDef.[[Key]]).
  3. Return ? DefineMethodProperty(object, methodDef.[[Key]], methodDef.[[Closure]], enumerable).
MethodDefinition : get ClassElementName ( ) { FunctionBody }
  1. Let propKey be the result of evaluating ClassElementName.
  2. ReturnIfAbrupt(propKey).
  3. Let scope be the running execution context's LexicalEnvironment.
  4. Let privateScope be the running execution context's PrivateEnvironment.
  5. Let sourceText be the source text matched by MethodDefinition.
  6. Let formalParameterList be an instance of the production FormalParameters : [empty] .
  7. Let closure be OrdinaryFunctionCreate(%Function.prototype%, sourceText, formalParameterList, FunctionBody, non-lexical-this, scope, privateScope).
  8. Perform MakeMethod(closure, object).
  9. Perform SetFunctionName(closure, propKey, "get").
  10. If propKey is a Private Name, then
    1. Return PrivateElement { [[Key]]: propKey, [[Kind]]: accessor, [[Get]]: closure, [[Set]]: undefined }.
  11. Else,
    1. Let desc be the PropertyDescriptor { [[Get]]: closure, [[Enumerable]]: enumerable, [[Configurable]]: true }.
    2. Perform ? DefinePropertyOrThrow(object, propKey, desc).
    3. Return empty.
MethodDefinition : set ClassElementName ( PropertySetParameterList ) { FunctionBody }
  1. Let propKey be the result of evaluating ClassElementName.
  2. ReturnIfAbrupt(propKey).
  3. Let scope be the running execution context's LexicalEnvironment.
  4. Let privateScope be the running execution context's PrivateEnvironment.
  5. Let sourceText be the source text matched by MethodDefinition.
  6. Let closure be OrdinaryFunctionCreate(%Function.prototype%, sourceText, PropertySetParameterList, FunctionBody, non-lexical-this, scope, privateScope).
  7. Perform MakeMethod(closure, object).
  8. Perform SetFunctionName(closure, propKey, "set").
  9. If propKey is a Private Name, then
    1. Return PrivateElement { [[Key]]: propKey, [[Kind]]: accessor, [[Get]]: undefined, [[Set]]: closure }.
  10. Else,
    1. Let desc be the PropertyDescriptor { [[Set]]: closure, [[Enumerable]]: enumerable, [[Configurable]]: true }.
    2. Perform ? DefinePropertyOrThrow(object, propKey, desc).
    3. Return empty.
GeneratorMethod : * ClassElementName ( UniqueFormalParameters ) { GeneratorBody }
  1. Let propKey be the result of evaluating ClassElementName.
  2. ReturnIfAbrupt(propKey).
  3. Let scope be the running execution context's LexicalEnvironment.
  4. Let privateScope be the running execution context's PrivateEnvironment.
  5. Let sourceText be the source text matched by GeneratorMethod.
  6. Let closure be OrdinaryFunctionCreate(%GeneratorFunction.prototype%, sourceText, UniqueFormalParameters, GeneratorBody, non-lexical-this, scope, privateScope).
  7. Perform MakeMethod(closure, object).
  8. Perform SetFunctionName(closure, propKey).
  9. Let prototype be ! OrdinaryObjectCreate(%GeneratorFunction.prototype.prototype%).
  10. Perform ! DefinePropertyOrThrow(closure, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }).
  11. Return ? DefineMethodProperty(object, propKey, closure, enumerable).
AsyncGeneratorMethod : async * ClassElementName ( UniqueFormalParameters ) { AsyncGeneratorBody }
  1. Let propKey be the result of evaluating ClassElementName.
  2. ReturnIfAbrupt(propKey).
  3. Let scope be the running execution context's LexicalEnvironment.
  4. Let privateScope be the running execution context's PrivateEnvironment.
  5. Let sourceText be the source text matched by AsyncGeneratorMethod.
  6. Let closure be ! OrdinaryFunctionCreate(%AsyncGeneratorFunction.prototype%, sourceText, UniqueFormalParameters, AsyncGeneratorBody, non-lexical-this, scope, privateScope).
  7. Perform ! MakeMethod(closure, object).
  8. Perform ! SetFunctionName(closure, propKey).
  9. Let prototype be ! OrdinaryObjectCreate(%AsyncGeneratorFunction.prototype.prototype%).
  10. Perform ! DefinePropertyOrThrow(closure, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }).
  11. Return ? DefineMethodProperty(object, propKey, closure, enumerable).
AsyncMethod : async ClassElementName ( UniqueFormalParameters ) { AsyncFunctionBody }
  1. Let propKey be the result of evaluating ClassElementName.
  2. ReturnIfAbrupt(propKey).
  3. Let scope be the LexicalEnvironment of the running execution context.
  4. Let privateScope be the running execution context's PrivateEnvironment.
  5. Let sourceText be the source text matched by AsyncMethod.
  6. Let closure be ! OrdinaryFunctionCreate(%AsyncFunction.prototype%, sourceText, UniqueFormalParameters, AsyncFunctionBody, non-lexical-this, scope, privateScope).
  7. Perform ! MakeMethod(closure, object).
  8. Perform ! SetFunctionName(closure, propKey).
  9. Return ? DefineMethodProperty(object, propKey, closure, enumerable).

15.5 Generator Function Definitions

Syntax

GeneratorDeclaration[Yield, Await, Default] : function * BindingIdentifier[?Yield, ?Await] ( FormalParameters[+Yield, ~Await] ) { GeneratorBody } [+Default] function * ( FormalParameters[+Yield, ~Await] ) { GeneratorBody } GeneratorExpression : function * BindingIdentifier[+Yield, ~Await]opt ( FormalParameters[+Yield, ~Await] ) { GeneratorBody } GeneratorMethod[Yield, Await] : * ClassElementName[?Yield, ?Await] ( UniqueFormalParameters[+Yield, ~Await] ) { GeneratorBody } GeneratorBody : FunctionBody[+Yield, ~Await] YieldExpression[In, Await] : yield yield [no LineTerminator here] AssignmentExpression[?In, +Yield, ?Await] yield [no LineTerminator here] * AssignmentExpression[?In, +Yield, ?Await] Note 1

The syntactic context immediately following yield requires use of the InputElementRegExpOrTemplateTail lexical goal.

Note 2

YieldExpression cannot be used within the FormalParameters of a generator function because any expressions that are part of FormalParameters are evaluated before the resulting Generator is in a resumable state.

Note 3

Abstract operations relating to Generators are defined in 27.5.3.

15.5.1 Static Semantics: Early Errors

GeneratorMethod : * ClassElementName ( UniqueFormalParameters ) { GeneratorBody } GeneratorDeclaration : function * BindingIdentifier ( FormalParameters ) { GeneratorBody } function * ( FormalParameters ) { GeneratorBody } GeneratorExpression : function * BindingIdentifieropt ( FormalParameters ) { GeneratorBody }

15.5.2 Runtime Semantics: EvaluateGeneratorBody

With parameters functionObject and argumentsList (a List).

GeneratorBody : FunctionBody
  1. Perform ? FunctionDeclarationInstantiation(functionObject, argumentsList).
  2. Let G be ? OrdinaryCreateFromConstructor(functionObject, "%GeneratorFunction.prototype.prototype%", « [[GeneratorState]], [[GeneratorContext]], [[GeneratorBrand]] »).
  3. Set G.[[GeneratorBrand]] to empty.
  4. Perform GeneratorStart(G, FunctionBody).
  5. Return Completion { [[Type]]: return, [[Value]]: G, [[Target]]: empty }.

15.5.3 Runtime Semantics: InstantiateGeneratorFunctionObject

With parameters scope and privateScope.

GeneratorDeclaration : function * BindingIdentifier ( FormalParameters ) { GeneratorBody }
  1. Let name be StringValue of BindingIdentifier.
  2. Let sourceText be the source text matched by GeneratorDeclaration.
  3. Let F be OrdinaryFunctionCreate(%GeneratorFunction.prototype%, sourceText, FormalParameters, GeneratorBody, non-lexical-this, scope, privateScope).
  4. Perform SetFunctionName(F, name).
  5. Let prototype be ! OrdinaryObjectCreate(%GeneratorFunction.prototype.prototype%).
  6. Perform DefinePropertyOrThrow(F, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }).
  7. Return F.
GeneratorDeclaration : function * ( FormalParameters ) { GeneratorBody }
  1. Let sourceText be the source text matched by GeneratorDeclaration.
  2. Let F be OrdinaryFunctionCreate(%GeneratorFunction.prototype%, sourceText, FormalParameters, GeneratorBody, non-lexical-this, scope, privateScope).
  3. Perform SetFunctionName(F, "default").
  4. Let prototype be ! OrdinaryObjectCreate(%GeneratorFunction.prototype.prototype%).
  5. Perform DefinePropertyOrThrow(F, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }).
  6. Return F.
Note

An anonymous GeneratorDeclaration can only occur as part of an export default declaration, and its function code is therefore always strict mode code.

15.5.4 Runtime Semantics: InstantiateGeneratorFunctionExpression

With optional parameter name.

GeneratorExpression : function * ( FormalParameters ) { GeneratorBody }
  1. If name is not present, set name to "".
  2. Let scope be the LexicalEnvironment of the running execution context.
  3. Let privateScope be the running execution context's PrivateEnvironment.
  4. Let sourceText be the source text matched by GeneratorExpression.
  5. Let closure be OrdinaryFunctionCreate(%GeneratorFunction.prototype%, sourceText, FormalParameters, GeneratorBody, non-lexical-this, scope, privateScope).
  6. Perform SetFunctionName(closure, name).
  7. Let prototype be ! OrdinaryObjectCreate(%GeneratorFunction.prototype.prototype%).
  8. Perform DefinePropertyOrThrow(closure, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }).
  9. Return closure.
GeneratorExpression : function * BindingIdentifier ( FormalParameters ) { GeneratorBody }
  1. Assert: name is not present.
  2. Set name to StringValue of BindingIdentifier.
  3. Let scope be the running execution context's LexicalEnvironment.
  4. Let funcEnv be NewDeclarativeEnvironment(scope).
  5. Perform funcEnv.CreateImmutableBinding(name, false).
  6. Let privateScope be the running execution context's PrivateEnvironment.
  7. Let sourceText be the source text matched by GeneratorExpression.
  8. Let closure be OrdinaryFunctionCreate(%GeneratorFunction.prototype%, sourceText, FormalParameters, GeneratorBody, non-lexical-this, funcEnv, privateScope).
  9. Perform SetFunctionName(closure, name).
  10. Let prototype be ! OrdinaryObjectCreate(%GeneratorFunction.prototype.prototype%).
  11. Perform DefinePropertyOrThrow(closure, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }).
  12. Perform funcEnv.InitializeBinding(name, closure).
  13. Return closure.
Note

The BindingIdentifier in a GeneratorExpression can be referenced from inside the GeneratorExpression's FunctionBody to allow the generator code to call itself recursively. However, unlike in a GeneratorDeclaration, the BindingIdentifier in a GeneratorExpression cannot be referenced from and does not affect the scope enclosing the GeneratorExpression.

15.5.5 Runtime Semantics: Evaluation

GeneratorExpression : function * BindingIdentifieropt ( FormalParameters ) { GeneratorBody }
  1. Return InstantiateGeneratorFunctionExpression of GeneratorExpression.
YieldExpression : yield
  1. Return ? Yield(undefined).
YieldExpression : yield AssignmentExpression
  1. Let exprRef be the result of evaluating AssignmentExpression.
  2. Let value be ? GetValue(exprRef).
  3. Return ? Yield(value).
YieldExpression : yield * AssignmentExpression
  1. Let generatorKind be ! GetGeneratorKind().
  2. Let exprRef be the result of evaluating AssignmentExpression.
  3. Let value be ? GetValue(exprRef).
  4. Let iteratorRecord be ? GetIterator(value, generatorKind).
  5. Let iterator be iteratorRecord.[[Iterator]].
  6. Let received be NormalCompletion(undefined).
  7. Repeat,
    1. If received.[[Type]] is normal, then
      1. Let innerResult be ? Call(iteratorRecord.[[NextMethod]], iteratorRecord.[[Iterator]], « received.[[Value]] »).
      2. If generatorKind is async, set innerResult to ? Await(innerResult).
      3. If Type(innerResult) is not Object, throw a TypeError exception.
      4. Let done be ? IteratorComplete(innerResult).
      5. If done is true, then
        1. Return ? IteratorValue(innerResult).
      6. If generatorKind is async, set received to AsyncGeneratorYield(? IteratorValue(innerResult)).
      7. Else, set received to GeneratorYield(innerResult).
    2. Else if received.[[Type]] is throw, then
      1. Let throw be ? GetMethod(iterator, "throw").
      2. If throw is not undefined, then
        1. Let innerResult be ? Call(throw, iterator, « received.[[Value]] »).
        2. If generatorKind is async, set innerResult to ? Await(innerResult).
        3. NOTE: Exceptions from the inner iterator throw method are propagated. Normal completions from an inner throw method are processed similarly to an inner next.
        4. If Type(innerResult) is not Object, throw a TypeError exception.
        5. Let done be ? IteratorComplete(innerResult).
        6. If done is true, then
          1. Return ? IteratorValue(innerResult).
        7. If generatorKind is async, set received to AsyncGeneratorYield(? IteratorValue(innerResult)).
        8. Else, set received to GeneratorYield(innerResult).
      3. Else,
        1. NOTE: If iterator does not have a throw method, this throw is going to terminate the yield* loop. But first we need to give iterator a chance to clean up.
        2. Let closeCompletion be Completion { [[Type]]: normal, [[Value]]: empty, [[Target]]: empty }.
        3. If generatorKind is async, perform ? AsyncIteratorClose(iteratorRecord, closeCompletion).
        4. Else, perform ? IteratorClose(iteratorRecord, closeCompletion).
        5. NOTE: The next step throws a TypeError to indicate that there was a yield* protocol violation: iterator does not have a throw method.
        6. Throw a TypeError exception.
    3. Else,
      1. Assert: received.[[Type]] is return.
      2. Let return be ? GetMethod(iterator, "return").
      3. If return is undefined, then
        1. If generatorKind is async, set received.[[Value]] to ? Await(received.[[Value]]).
        2. Return Completion(received).
      4. Let innerReturnResult be ? Call(return, iterator, « received.[[Value]] »).
      5. If generatorKind is async, set innerReturnResult to ? Await(innerReturnResult).
      6. If Type(innerReturnResult) is not Object, throw a TypeError exception.
      7. Let done be ? IteratorComplete(innerReturnResult).
      8. If done is true, then
        1. Let value be ? IteratorValue(innerReturnResult).
        2. Return Completion { [[Type]]: return, [[Value]]: value, [[Target]]: empty }.
      9. If generatorKind is async, set received to AsyncGeneratorYield(? IteratorValue(innerReturnResult)).
      10. Else, set received to GeneratorYield(innerReturnResult).

15.6 Async Generator Function Definitions

Syntax

AsyncGeneratorDeclaration[Yield, Await, Default] : async [no LineTerminator here] function * BindingIdentifier[?Yield, ?Await] ( FormalParameters[+Yield, +Await] ) { AsyncGeneratorBody } [+Default] async [no LineTerminator here] function * ( FormalParameters[+Yield, +Await] ) { AsyncGeneratorBody } AsyncGeneratorExpression : async [no LineTerminator here] function * BindingIdentifier[+Yield, +Await]opt ( FormalParameters[+Yield, +Await] ) { AsyncGeneratorBody } AsyncGeneratorMethod[Yield, Await] : async [no LineTerminator here] * ClassElementName[?Yield, ?Await] ( UniqueFormalParameters[+Yield, +Await] ) { AsyncGeneratorBody } AsyncGeneratorBody : FunctionBody[+Yield, +Await] Note 1

YieldExpression and AwaitExpression cannot be used within the FormalParameters of an async generator function because any expressions that are part of FormalParameters are evaluated before the resulting AsyncGenerator is in a resumable state.

Note 2

Abstract operations relating to AsyncGenerators are defined in 27.6.3.

15.6.1 Static Semantics: Early Errors

AsyncGeneratorMethod : async * ClassElementName ( UniqueFormalParameters ) { AsyncGeneratorBody } AsyncGeneratorDeclaration : async function * BindingIdentifier ( FormalParameters ) { AsyncGeneratorBody } async function * ( FormalParameters ) { AsyncGeneratorBody } AsyncGeneratorExpression : async function * BindingIdentifieropt ( FormalParameters ) { AsyncGeneratorBody }

15.6.2 Runtime Semantics: EvaluateAsyncGeneratorBody

With parameters functionObject and argumentsList (a List).

AsyncGeneratorBody : FunctionBody
  1. Perform ? FunctionDeclarationInstantiation(functionObject, argumentsList).
  2. Let generator be ? OrdinaryCreateFromConstructor(functionObject, "%AsyncGeneratorFunction.prototype.prototype%", « [[AsyncGeneratorState]], [[AsyncGeneratorContext]], [[AsyncGeneratorQueue]], [[GeneratorBrand]] »).
  3. Set generator.[[GeneratorBrand]] to empty.
  4. Perform ! AsyncGeneratorStart(generator, FunctionBody).
  5. Return Completion { [[Type]]: return, [[Value]]: generator, [[Target]]: empty }.

15.6.3 Runtime Semantics: InstantiateAsyncGeneratorFunctionObject

With parameters scope and privateScope.

AsyncGeneratorDeclaration : async function * BindingIdentifier ( FormalParameters ) { AsyncGeneratorBody }
  1. Let name be StringValue of BindingIdentifier.
  2. Let sourceText be the source text matched by AsyncGeneratorDeclaration.
  3. Let F be ! OrdinaryFunctionCreate(%AsyncGeneratorFunction.prototype%, sourceText, FormalParameters, AsyncGeneratorBody, non-lexical-this, scope, privateScope).
  4. Perform ! SetFunctionName(F, name).
  5. Let prototype be ! OrdinaryObjectCreate(%AsyncGeneratorFunction.prototype.prototype%).
  6. Perform ! DefinePropertyOrThrow(F, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }).
  7. Return F.
AsyncGeneratorDeclaration : async function * ( FormalParameters ) { AsyncGeneratorBody }
  1. Let sourceText be the source text matched by AsyncGeneratorDeclaration.
  2. Let F be OrdinaryFunctionCreate(%AsyncGeneratorFunction.prototype%, sourceText, FormalParameters, AsyncGeneratorBody, non-lexical-this, scope, privateScope).
  3. Perform SetFunctionName(F, "default").
  4. Let prototype be ! OrdinaryObjectCreate(%AsyncGeneratorFunction.prototype.prototype%).
  5. Perform DefinePropertyOrThrow(F, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }).
  6. Return F.
Note

An anonymous AsyncGeneratorDeclaration can only occur as part of an export default declaration.

15.6.4 Runtime Semantics: InstantiateAsyncGeneratorFunctionExpression

With optional parameter name.

AsyncGeneratorExpression : async function * ( FormalParameters ) { AsyncGeneratorBody }
  1. If name is not present, set name to "".
  2. Let scope be the LexicalEnvironment of the running execution context.
  3. Let privateScope be the running execution context's PrivateEnvironment.
  4. Let sourceText be the source text matched by AsyncGeneratorExpression.
  5. Let closure be ! OrdinaryFunctionCreate(%AsyncGeneratorFunction.prototype%, sourceText, FormalParameters, AsyncGeneratorBody, non-lexical-this, scope, privateScope).
  6. Perform SetFunctionName(closure, name).
  7. Let prototype be ! OrdinaryObjectCreate(%AsyncGeneratorFunction.prototype.prototype%).
  8. Perform ! DefinePropertyOrThrow(closure, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }).
  9. Return closure.
AsyncGeneratorExpression : async function * BindingIdentifier ( FormalParameters ) { AsyncGeneratorBody }
  1. Assert: name is not present.
  2. Set name to StringValue of BindingIdentifier.
  3. Let scope be the running execution context's LexicalEnvironment.
  4. Let funcEnv be ! NewDeclarativeEnvironment(scope).
  5. Perform ! funcEnv.CreateImmutableBinding(name, false).
  6. Let privateScope be the running execution context's PrivateEnvironment.
  7. Let sourceText be the source text matched by AsyncGeneratorExpression.
  8. Let closure be ! OrdinaryFunctionCreate(%AsyncGeneratorFunction.prototype%, sourceText, FormalParameters, AsyncGeneratorBody, non-lexical-this, funcEnv, privateScope).
  9. Perform ! SetFunctionName(closure, name).
  10. Let prototype be ! OrdinaryObjectCreate(%AsyncGeneratorFunction.prototype.prototype%).
  11. Perform ! DefinePropertyOrThrow(closure, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }).
  12. Perform ! funcEnv.InitializeBinding(name, closure).
  13. Return closure.
Note

The BindingIdentifier in an AsyncGeneratorExpression can be referenced from inside the AsyncGeneratorExpression's AsyncGeneratorBody to allow the generator code to call itself recursively. However, unlike in an AsyncGeneratorDeclaration, the BindingIdentifier in an AsyncGeneratorExpression cannot be referenced from and does not affect the scope enclosing the AsyncGeneratorExpression.

15.6.5 Runtime Semantics: Evaluation

AsyncGeneratorExpression : async function * BindingIdentifieropt ( FormalParameters ) { AsyncGeneratorBody }
  1. Return InstantiateAsyncGeneratorFunctionExpression of AsyncGeneratorExpression.

15.7 Class Definitions

Syntax

ClassDeclaration[Yield, Await, Default] : class BindingIdentifier[?Yield, ?Await] ClassTail[?Yield, ?Await] [+Default] class ClassTail[?Yield, ?Await] ClassExpression[Yield, Await] : class BindingIdentifier[?Yield, ?Await]opt ClassTail[?Yield, ?Await] ClassTail[Yield, Await] : ClassHeritage[?Yield, ?Await]opt { ClassBody[?Yield, ?Await]opt } ClassHeritage[Yield, Await] : extends LeftHandSideExpression[?Yield, ?Await] ClassBody[Yield, Await] : ClassElementList[?Yield, ?Await] ClassElementList[Yield, Await] : ClassElement[?Yield, ?Await] ClassElementList[?Yield, ?Await] ClassElement[?Yield, ?Await] ClassElement[Yield, Await] : MethodDefinition[?Yield, ?Await] static MethodDefinition[?Yield, ?Await] FieldDefinition[?Yield, ?Await] ; static FieldDefinition[?Yield, ?Await] ; ClassStaticBlock ; FieldDefinition[Yield, Await] : ClassElementName[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]opt ClassElementName[Yield, Await] : PropertyName[?Yield, ?Await] PrivateIdentifier ClassStaticBlock : static { ClassStaticBlockBody } ClassStaticBlockBody : ClassStaticBlockStatementList ClassStaticBlockStatementList : StatementList[~Yield, +Await, ~Return]opt Note

A class definition is always strict mode code.

15.7.1 Static Semantics: Early Errors

ClassTail : ClassHeritageopt { ClassBody } ClassBody : ClassElementList ClassElement : MethodDefinition ClassElement : static MethodDefinition ClassElement : FieldDefinition ; ClassElement : static FieldDefinition ; FieldDefinition : ClassElementName Initializeropt ClassElementName : PrivateIdentifier ClassStaticBlockBody : ClassStaticBlockStatementList

15.7.2 Static Semantics: ClassElementKind

ClassElement : MethodDefinition
  1. If PropName of MethodDefinition is "constructor", return ConstructorMethod.
  2. Return NonConstructorMethod.
ClassElement : static MethodDefinition FieldDefinition ; static FieldDefinition ;
  1. Return NonConstructorMethod.
ClassElement : ClassStaticBlock
  1. Return NonConstructorMethod.
ClassElement : ;
  1. Return empty.

15.7.3 Static Semantics: ConstructorMethod

ClassElementList : ClassElement
  1. If ClassElementKind of ClassElement is ConstructorMethod, return ClassElement.
  2. Return empty.
ClassElementList : ClassElementList ClassElement
  1. Let head be ConstructorMethod of ClassElementList.
  2. If head is not empty, return head.
  3. If ClassElementKind of ClassElement is ConstructorMethod, return ClassElement.
  4. Return empty.
Note

Early Error rules ensure that there is only one method definition named "constructor" and that it is not an accessor property or generator definition.

15.7.4 Static Semantics: IsStatic

ClassElement : MethodDefinition
  1. Return false.
ClassElement : static MethodDefinition
  1. Return true.
ClassElement : FieldDefinition ;
  1. Return false.
ClassElement : static FieldDefinition ;
  1. Return true.
ClassElement : ClassStaticBlock
  1. Return true.
ClassElement : ;
  1. Return false.

15.7.5 Static Semantics: NonConstructorElements

ClassElementList : ClassElement
  1. If ClassElementKind of ClassElement is NonConstructorMethod, then
    1. Return a List whose sole element is ClassElement.
  2. Return a new empty List.
ClassElementList : ClassElementList ClassElement
  1. Let list be NonConstructorElements of ClassElementList.
  2. If ClassElementKind of ClassElement is NonConstructorMethod, then
    1. Append ClassElement to the end of list.
  3. Return list.

15.7.6 Static Semantics: PrototypePropertyNameList

ClassElementList : ClassElement
  1. Let propName be PropName of ClassElement.
  2. If propName is empty, return a new empty List.
  3. If IsStatic of ClassElement is true, return a new empty List.
  4. Return a List whose sole element is propName.
ClassElementList : ClassElementList ClassElement
  1. Let list be PrototypePropertyNameList of ClassElementList.
  2. Let propName be PropName of ClassElement.
  3. If propName is empty, return list.
  4. If IsStatic of ClassElement is true, return list.
  5. Return the list-concatenation of list and « propName ».

15.7.7 Static Semantics: AllPrivateIdentifiersValid

With parameter names.

Every grammar production alternative in this specification which is not listed below implicitly has the following default definition of AllPrivateIdentifiersValid:

  1. For each child node child of this Parse Node, do
    1. If child is an instance of a nonterminal, then
      1. If AllPrivateIdentifiersValid of child with argument names is false, return false.
  2. Return true.
MemberExpression : MemberExpression . PrivateIdentifier
  1. If names contains the StringValue of PrivateIdentifier, then
    1. Return AllPrivateIdentifiersValid of MemberExpression with argument names.
  2. Return false.
CallExpression : CallExpression . PrivateIdentifier
  1. If names contains the StringValue of PrivateIdentifier, then
    1. Return AllPrivateIdentifiersValid of CallExpression with argument names.
  2. Return false.
OptionalChain : ?. PrivateIdentifier
  1. If names contains the StringValue of PrivateIdentifier, return true.
  2. Return false.
OptionalChain : OptionalChain . PrivateIdentifier
  1. If names contains the StringValue of PrivateIdentifier, then
    1. Return AllPrivateIdentifiersValid of OptionalChain with argument names.
  2. Return false.
ClassBody : ClassElementList
  1. Let newNames be the list-concatenation of names and PrivateBoundIdentifiers of ClassBody.
  2. Return AllPrivateIdentifiersValid of ClassElementList with argument newNames.
RelationalExpression : PrivateIdentifier in ShiftExpression
  1. If names contains the StringValue of PrivateIdentifier, then
    1. Return AllPrivateIdentifiersValid of ShiftExpression with argument names.
  2. Return false.

15.7.8 Static Semantics: PrivateBoundIdentifiers

FieldDefinition : ClassElementName Initializeropt
  1. Return PrivateBoundIdentifiers of ClassElementName.
ClassElementName : PrivateIdentifier
  1. Return a List whose sole element is the StringValue of PrivateIdentifier.
ClassElementName : PropertyName ClassElement : ClassStaticBlock ClassElement : ;
  1. Return a new empty List.
ClassElementList : ClassElementList ClassElement
  1. Let names1 be PrivateBoundIdentifiers of ClassElementList.
  2. Let names2 be PrivateBoundIdentifiers of ClassElement.
  3. Return the list-concatenation of names1 and names2.
MethodDefinition : ClassElementName ( UniqueFormalParameters ) { FunctionBody } get ClassElementName ( ) { FunctionBody } set ClassElementName ( PropertySetParameterList ) { FunctionBody } GeneratorMethod : * ClassElementName ( UniqueFormalParameters ) { GeneratorBody } AsyncMethod : async ClassElementName ( UniqueFormalParameters ) { AsyncFunctionBody } AsyncGeneratorMethod : async * ClassElementName ( UniqueFormalParameters ) { AsyncGeneratorBody }
  1. Return PrivateBoundIdentifiers of ClassElementName.

15.7.9 Static Semantics: ContainsArguments

Every grammar production alternative in this specification which is not listed below implicitly has the following default definition of ContainsArguments:

  1. For each child node child of this Parse Node, do
    1. If child is an instance of a nonterminal, then
      1. If ContainsArguments of child is true, return true.
  2. Return false.
IdentifierReference : Identifier
  1. If the StringValue of Identifier is "arguments", return true.
  2. Return false.
FunctionDeclaration : function BindingIdentifier ( FormalParameters ) { FunctionBody } function ( FormalParameters ) { FunctionBody } FunctionExpression : function BindingIdentifieropt ( FormalParameters ) { FunctionBody } GeneratorDeclaration : function * BindingIdentifier ( FormalParameters ) { GeneratorBody } function * ( FormalParameters ) { GeneratorBody } GeneratorExpression : function * BindingIdentifieropt ( FormalParameters ) { GeneratorBody } AsyncGeneratorDeclaration : async function * BindingIdentifier ( FormalParameters ) { AsyncGeneratorBody } async function * ( FormalParameters ) { AsyncGeneratorBody } AsyncGeneratorExpression : async function * BindingIdentifieropt ( FormalParameters ) { AsyncGeneratorBody } AsyncFunctionDeclaration : async function BindingIdentifier ( FormalParameters ) { AsyncFunctionBody } async function ( FormalParameters ) { AsyncFunctionBody } AsyncFunctionExpression : async function BindingIdentifieropt ( FormalParameters ) { AsyncFunctionBody }
  1. Return false.
MethodDefinition : ClassElementName ( UniqueFormalParameters ) { FunctionBody } get ClassElementName ( ) { FunctionBody } set ClassElementName ( PropertySetParameterList ) { FunctionBody } GeneratorMethod : * ClassElementName ( UniqueFormalParameters ) { GeneratorBody } AsyncGeneratorMethod : async * ClassElementName ( UniqueFormalParameters ) { AsyncGeneratorBody } AsyncMethod : async ClassElementName ( UniqueFormalParameters ) { AsyncFunctionBody }
  1. Return ContainsArguments of ClassElementName.

15.7.10 Runtime Semantics: ClassFieldDefinitionEvaluation

With parameter homeObject.

FieldDefinition : ClassElementName Initializeropt
  1. Let name be the result of evaluating ClassElementName.
  2. ReturnIfAbrupt(name).
  3. If Initializeropt is present, then
    1. Let formalParameterList be an instance of the production FormalParameters : [empty] .
    2. Let scope be the LexicalEnvironment of the running execution context.
    3. Let privateScope be the running execution context's PrivateEnvironment.
    4. Let sourceText be the empty sequence of Unicode code points.
    5. Let initializer be ! OrdinaryFunctionCreate(%Function.prototype%, sourceText, formalParameterList, Initializer, non-lexical-this, scope, privateScope).
    6. Perform MakeMethod(initializer, homeObject).
    7. Set initializer.[[ClassFieldInitializerName]] to name.
  4. Else,
    1. Let initializer be empty.
  5. Return the ClassFieldDefinition Record { [[Name]]: name, [[Initializer]]: initializer }.
Note
The function created for initializer is never directly accessible to ECMAScript code.

15.7.11 Runtime Semantics: ClassStaticBlockDefinitionEvaluation

With parameter homeObject.

ClassStaticBlock : static { ClassStaticBlockBody }
  1. Let lex be the running execution context's LexicalEnvironment.
  2. Let privateScope be the running execution context's PrivateEnvironment.
  3. Let sourceText be the empty sequence of Unicode code points.
  4. Let formalParameters be an instance of the production FormalParameters : [empty] .
  5. Let bodyFunction be OrdinaryFunctionCreate(%Function.prototype%, sourceText, formalParameters, ClassStaticBlockBody, non-lexical-this, lex, privateScope).
  6. Perform MakeMethod(bodyFunction, homeObject).
  7. Return the ClassStaticBlockDefinition Record { [[BodyFunction]]: bodyFunction }.
Note
The function bodyFunction is never directly accessible to ECMAScript code.

15.7.12 Runtime Semantics: EvaluateClassStaticBlockBody

With parameter functionObject.

ClassStaticBlockBody : ClassStaticBlockStatementList
  1. Perform ? FunctionDeclarationInstantiation(functionObject, « »).
  2. Return the result of evaluating ClassStaticBlockStatementList.

15.7.13 Runtime Semantics: ClassElementEvaluation

With parameter object.

ClassElement : FieldDefinition ; ClassElement : static FieldDefinition ;
  1. Return ClassFieldDefinitionEvaluation of FieldDefinition with argument object.
ClassElement : MethodDefinition ClassElement : static MethodDefinition
  1. Return MethodDefinitionEvaluation of MethodDefinition with arguments object and false.
ClassElement : ClassStaticBlock
  1. Return ClassStaticBlockDefinitionEvaluation of ClassStaticBlock with argument object.
ClassElement : ;
  1. Return.

15.7.14 Runtime Semantics: ClassDefinitionEvaluation

With parameters classBinding and className.

Note

For ease of specification, private methods and accessors are included alongside private fields in the [[PrivateElements]] slot of class instances. However, any given object has either all or none of the private methods and accessors defined by a given class. This feature has been designed so that implementations may choose to implement private methods and accessors using a strategy which does not require tracking each method or accessor individually.

For example, an implementation could directly associate instance private methods with their corresponding Private Name and track, for each object, which class constructors have run with that object as their this value. Looking up an instance private method on an object then consists of checking that the class constructor which defines the method has been used to initialize the object, then returning the method associated with the Private Name.

This differs from private fields: because field initializers can throw during class instantiation, an individual object may have some proper subset of the private fields of a given class, and so private fields must in general be tracked individually.

ClassTail : ClassHeritageopt { ClassBodyopt }
  1. Let env be the LexicalEnvironment of the running execution context.
  2. Let classScope be NewDeclarativeEnvironment(env).
  3. If classBinding is not undefined, then
    1. Perform classScope.CreateImmutableBinding(classBinding, true).
  4. Let outerPrivateEnvironment be the running execution context's PrivateEnvironment.
  5. Let classPrivateEnvironment be NewPrivateEnvironment(outerPrivateEnvironment).
  6. If ClassBodyopt is present, then
    1. For each String dn of the PrivateBoundIdentifiers of ClassBodyopt, do
      1. If classPrivateEnvironment.[[Names]] contains a Private Name whose [[Description]] is dn, then
        1. Assert: This is only possible for getter/setter pairs.
      2. Else,
        1. Let name be a new Private Name whose [[Description]] value is dn.
        2. Append name to classPrivateEnvironment.[[Names]].
  7. If ClassHeritageopt is not present, then
    1. Let protoParent be %Object.prototype%.
    2. Let constructorParent be %Function.prototype%.
  8. Else,
    1. Set the running execution context's LexicalEnvironment to classScope.
    2. NOTE: The running execution context's PrivateEnvironment is outerPrivateEnvironment when evaluating ClassHeritage.
    3. Let superclassRef be the result of evaluating ClassHeritage.
    4. Set the running execution context's LexicalEnvironment to env.
    5. Let superclass be ? GetValue(superclassRef).
    6. If superclass is null, then
      1. Let protoParent be null.
      2. Let constructorParent be %Function.prototype%.
    7. Else if IsConstructor(superclass) is false, throw a TypeError exception.
    8. Else,
      1. Let protoParent be ? Get(superclass, "prototype").
      2. If Type(protoParent) is neither Object nor Null, throw a TypeError exception.
      3. Let constructorParent be superclass.
  9. Let proto be ! OrdinaryObjectCreate(protoParent).
  10. If ClassBodyopt is not present, let constructor be empty.
  11. Else, let constructor be ConstructorMethod of ClassBody.
  12. Set the running execution context's LexicalEnvironment to classScope.
  13. Set the running execution context's PrivateEnvironment to classPrivateEnvironment.
  14. If constructor is empty, then
    1. Let defaultConstructor be a new Abstract Closure with no parameters that captures nothing and performs the following steps when called:
      1. Let args be the List of arguments that was passed to this function by [[Call]] or [[Construct]].
      2. If NewTarget is undefined, throw a TypeError exception.
      3. Let F be the active function object.
      4. If F.[[ConstructorKind]] is derived, then
        1. NOTE: This branch behaves similarly to constructor(...args) { super(...args); }. The most notable distinction is that while the aforementioned ECMAScript source text observably calls the @@iterator method on %Array.prototype%, this function does not.
        2. Let func be ! F.[[GetPrototypeOf]]().
        3. If IsConstructor(func) is false, throw a TypeError exception.
        4. Return ? Construct(func, args, NewTarget).
      5. Else,
        1. NOTE: This branch behaves similarly to constructor() {}.
        2. Return ? OrdinaryCreateFromConstructor(NewTarget, "%Object.prototype%").
    2. Let F be ! CreateBuiltinFunction(defaultConstructor, 0, className, « [[ConstructorKind]], [[SourceText]] », the current Realm Record, constructorParent).
  15. Else,
    1. Let constructorInfo be ! DefineMethod of constructor with arguments proto and constructorParent.
    2. Let F be constructorInfo.[[Closure]].
    3. Perform ! MakeClassConstructor(F).
    4. Perform ! SetFunctionName(F, className).
  16. Perform ! MakeConstructor(F, false, proto).
  17. If ClassHeritageopt is present, set F.[[ConstructorKind]] to derived.
  18. Perform ! CreateMethodProperty(proto, "constructor", F).
  19. If ClassBodyopt is not present, let elements be a new empty List.
  20. Else, let elements be NonConstructorElements of ClassBody.
  21. Let instancePrivateMethods be a new empty List.
  22. Let staticPrivateMethods be a new empty List.
  23. Let instanceFields be a new empty List.
  24. Let staticElements be a new empty List.
  25. For each ClassElement e of elements, do
    1. If IsStatic of e is false, then
      1. Let element be ClassElementEvaluation of e with argument proto.
    2. Else,
      1. Let element be ClassElementEvaluation of e with argument F.
    3. If element is an abrupt completion, then
      1. Set the running execution context's LexicalEnvironment to env.
      2. Set the running execution context's PrivateEnvironment to outerPrivateEnvironment.
      3. Return Completion(element).
    4. Set element to element.[[Value]].
    5. If element is a PrivateElement, then
      1. Assert: element.[[Kind]] is either method or accessor.
      2. If IsStatic of e is false, let container be instancePrivateMethods.
      3. Else, let container be staticPrivateMethods.
      4. If container contains a PrivateElement whose [[Key]] is element.[[Key]], then
        1. Let existing be that PrivateElement.
        2. Assert: element.[[Kind]] and existing.[[Kind]] are both accessor.
        3. If element.[[Get]] is undefined, then
          1. Let combined be PrivateElement { [[Key]]: element.[[Key]], [[Kind]]: accessor, [[Get]]: existing.[[Get]], [[Set]]: element.[[Set]] }.
        4. Else,
          1. Let combined be PrivateElement { [[Key]]: element.[[Key]], [[Kind]]: accessor, [[Get]]: element.[[Get]], [[Set]]: existing.[[Set]] }.
        5. Replace existing in container with combined.
      5. Else,
        1. Append element to container.
    6. Else if element is a ClassFieldDefinition Record, then
      1. If IsStatic of e is false, append element to instanceFields.
      2. Else, append element to staticElements.
    7. Else if element is a ClassStaticBlockDefinition Record, then
      1. Append element to staticElements.
  26. Set the running execution context's LexicalEnvironment to env.
  27. If classBinding is not undefined, then
    1. Perform classScope.InitializeBinding(classBinding, F).
  28. Set F.[[PrivateMethods]] to instancePrivateMethods.
  29. Set F.[[Fields]] to instanceFields.
  30. For each PrivateElement method of staticPrivateMethods, do
    1. Perform ! PrivateMethodOrAccessorAdd(F, method).
  31. For each element elementRecord of staticElements, do
    1. If elementRecord is a ClassFieldDefinition Record, then
      1. Let result be DefineField(F, elementRecord).
    2. Else,
      1. Assert: elementRecord is a ClassStaticBlockDefinition Record.
      2. Let result be ? Call(elementRecord.[[BodyFunction]], F).
    3. If result is an abrupt completion, then
      1. Set the running execution context's PrivateEnvironment to outerPrivateEnvironment.
      2. Return result.
  32. Set the running execution context's PrivateEnvironment to outerPrivateEnvironment.
  33. Return F.

15.7.15 Runtime Semantics: BindingClassDeclarationEvaluation

ClassDeclaration : class BindingIdentifier ClassTail
  1. Let className be StringValue of BindingIdentifier.
  2. Let value be ? ClassDefinitionEvaluation of ClassTail with arguments className and className.
  3. Set value.[[SourceText]] to the source text matched by ClassDeclaration.
  4. Let env be the running execution context's LexicalEnvironment.
  5. Perform ? InitializeBoundName(className, value, env).
  6. Return value.
ClassDeclaration : class ClassTail
  1. Let value be ? ClassDefinitionEvaluation of ClassTail with arguments undefined and "default".
  2. Set value.[[SourceText]] to the source text matched by ClassDeclaration.
  3. Return value.
Note

ClassDeclaration : class ClassTail only occurs as part of an ExportDeclaration and establishing its binding is handled as part of the evaluation action for that production. See 16.2.3.7.

15.7.16 Runtime Semantics: Evaluation

ClassDeclaration : class BindingIdentifier ClassTail
  1. Perform ? BindingClassDeclarationEvaluation of this ClassDeclaration.
  2. Return NormalCompletion(empty).
Note

ClassDeclaration : class ClassTail only occurs as part of an ExportDeclaration and is never directly evaluated.

ClassExpression : class ClassTail
  1. Let value be ? ClassDefinitionEvaluation of ClassTail with arguments undefined and "".
  2. Set value.[[SourceText]] to the source text matched by ClassExpression.
  3. Return value.
ClassExpression : class BindingIdentifier ClassTail
  1. Let className be StringValue of BindingIdentifier.
  2. Let value be ? ClassDefinitionEvaluation of ClassTail with arguments className and className.
  3. Set value.[[SourceText]] to the source text matched by ClassExpression.
  4. Return value.
ClassElementName : PrivateIdentifier
  1. Let privateIdentifier be StringValue of PrivateIdentifier.
  2. Let privateEnvRec be the running execution context's PrivateEnvironment.
  3. Let names be privateEnvRec.[[Names]].
  4. Assert: Exactly one element of names is a Private Name whose [[Description]] is privateIdentifier.
  5. Let privateName be the Private Name in names whose [[Description]] is privateIdentifier.
  6. Return privateName.
ClassStaticBlockStatementList : [empty]
  1. Return NormalCompletion(undefined).

15.8 Async Function Definitions

Syntax

AsyncFunctionDeclaration[Yield, Await, Default] : async [no LineTerminator here] function BindingIdentifier[?Yield, ?Await] ( FormalParameters[~Yield, +Await] ) { AsyncFunctionBody } [+Default] async [no LineTerminator here] function ( FormalParameters[~Yield, +Await] ) { AsyncFunctionBody } AsyncFunctionExpression : async [no LineTerminator here] function BindingIdentifier[~Yield, +Await]opt ( FormalParameters[~Yield, +Await] ) { AsyncFunctionBody } AsyncMethod[Yield, Await] : async [no LineTerminator here] ClassElementName[?Yield, ?Await] ( UniqueFormalParameters[~Yield, +Await] ) { AsyncFunctionBody } AsyncFunctionBody : FunctionBody[~Yield, +Await] AwaitExpression[Yield] : await UnaryExpression[?Yield, +Await] Note 1

await is parsed as a keyword of an AwaitExpression when the [Await] parameter is present. The [Await] parameter is present in the top level of the following contexts, although the parameter may be absent in some contexts depending on the nonterminals, such as FunctionBody:

When Script is the syntactic goal symbol, await may be parsed as an identifier when the [Await] parameter is absent. This includes the following contexts:

Note 2

Unlike YieldExpression, it is a Syntax Error to omit the operand of an AwaitExpression. You must await something.

15.8.1 Static Semantics: Early Errors

AsyncMethod : async ClassElementName ( UniqueFormalParameters ) { AsyncFunctionBody } AsyncFunctionDeclaration : async function BindingIdentifier ( FormalParameters ) { AsyncFunctionBody } async function ( FormalParameters ) { AsyncFunctionBody } AsyncFunctionExpression : async function BindingIdentifieropt ( FormalParameters ) { AsyncFunctionBody }

15.8.2 Runtime Semantics: InstantiateAsyncFunctionObject

With parameters scope and privateScope.

AsyncFunctionDeclaration : async function BindingIdentifier ( FormalParameters ) { AsyncFunctionBody }
  1. Let name be StringValue of BindingIdentifier.
  2. Let sourceText be the source text matched by AsyncFunctionDeclaration.
  3. Let F be ! OrdinaryFunctionCreate(%AsyncFunction.prototype%, sourceText, FormalParameters, AsyncFunctionBody, non-lexical-this, scope, privateScope).
  4. Perform ! SetFunctionName(F, name).
  5. Return F.
AsyncFunctionDeclaration : async function ( FormalParameters ) { AsyncFunctionBody }
  1. Let sourceText be the source text matched by AsyncFunctionDeclaration.
  2. Let F be ! OrdinaryFunctionCreate(%AsyncFunction.prototype%, sourceText, FormalParameters, AsyncFunctionBody, non-lexical-this, scope, privateScope).
  3. Perform ! SetFunctionName(F, "default").
  4. Return F.

15.8.3 Runtime Semantics: InstantiateAsyncFunctionExpression

With optional parameter name.

AsyncFunctionExpression : async function ( FormalParameters ) { AsyncFunctionBody }
  1. If name is not present, set name to "".
  2. Let scope be the LexicalEnvironment of the running execution context.
  3. Let privateScope be the running execution context's PrivateEnvironment.
  4. Let sourceText be the source text matched by AsyncFunctionExpression.
  5. Let closure be ! OrdinaryFunctionCreate(%AsyncFunction.prototype%, sourceText, FormalParameters, AsyncFunctionBody, non-lexical-this, scope, privateScope).
  6. Perform SetFunctionName(closure, name).
  7. Return closure.
AsyncFunctionExpression : async function BindingIdentifier ( FormalParameters ) { AsyncFunctionBody }
  1. Assert: name is not present.
  2. Set name to StringValue of BindingIdentifier.
  3. Let scope be the LexicalEnvironment of the running execution context.
  4. Let funcEnv be ! NewDeclarativeEnvironment(scope).
  5. Perform ! funcEnv.CreateImmutableBinding(name, false).
  6. Let privateScope be the running execution context's PrivateEnvironment.
  7. Let sourceText be the source text matched by AsyncFunctionExpression.
  8. Let closure be ! OrdinaryFunctionCreate(%AsyncFunction.prototype%, sourceText, FormalParameters, AsyncFunctionBody, non-lexical-this, funcEnv, privateScope).
  9. Perform ! SetFunctionName(closure, name).
  10. Perform ! funcEnv.InitializeBinding(name, closure).
  11. Return closure.
Note

The BindingIdentifier in an AsyncFunctionExpression can be referenced from inside the AsyncFunctionExpression's AsyncFunctionBody to allow the function to call itself recursively. However, unlike in a FunctionDeclaration, the BindingIdentifier in a AsyncFunctionExpression cannot be referenced from and does not affect the scope enclosing the AsyncFunctionExpression.

15.8.4 Runtime Semantics: EvaluateAsyncFunctionBody

With parameters functionObject and argumentsList (a List).

AsyncFunctionBody : FunctionBody
  1. Let promiseCapability be ! NewPromiseCapability(%Promise%).
  2. Let declResult be FunctionDeclarationInstantiation(functionObject, argumentsList).
  3. If declResult is not an abrupt completion, then
    1. Perform ! AsyncFunctionStart(promiseCapability, FunctionBody).
  4. Else,
    1. Perform ! Call(promiseCapability.[[Reject]], undefined, « declResult.[[Value]] »).
  5. Return Completion { [[Type]]: return, [[Value]]: promiseCapability.[[Promise]], [[Target]]: empty }.

15.8.5 Runtime Semantics: Evaluation

AsyncFunctionExpression : async function BindingIdentifieropt ( FormalParameters ) { AsyncFunctionBody }
  1. Return InstantiateAsyncFunctionExpression of AsyncFunctionExpression.
AwaitExpression : await UnaryExpression
  1. Let exprRef be the result of evaluating UnaryExpression.
  2. Let value be ? GetValue(exprRef).
  3. Return ? Await(value).

15.9 Async Arrow Function Definitions

Syntax

AsyncArrowFunction[In, Yield, Await] : async [no LineTerminator here] AsyncArrowBindingIdentifier[?Yield] [no LineTerminator here] => AsyncConciseBody[?In] CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await] [no LineTerminator here] => AsyncConciseBody[?In] AsyncConciseBody[In] : [lookahead ≠ {] ExpressionBody[?In, +Await] { AsyncFunctionBody } AsyncArrowBindingIdentifier[Yield] : BindingIdentifier[?Yield, +Await] CoverCallExpressionAndAsyncArrowHead[Yield, Await] : MemberExpression[?Yield, ?Await] Arguments[?Yield, ?Await]

Supplemental Syntax

When processing an instance of the production
AsyncArrowFunction : CoverCallExpressionAndAsyncArrowHead => AsyncConciseBody
the interpretation of CoverCallExpressionAndAsyncArrowHead is refined using the following grammar:

AsyncArrowHead : async [no LineTerminator here] ArrowFormalParameters[~Yield, +Await]

15.9.1 Static Semantics: Early Errors

AsyncArrowFunction : async AsyncArrowBindingIdentifier => AsyncConciseBody AsyncArrowFunction : CoverCallExpressionAndAsyncArrowHead => AsyncConciseBody

15.9.2 Static Semantics: AsyncConciseBodyContainsUseStrict

AsyncConciseBody : ExpressionBody
  1. Return false.
AsyncConciseBody : { AsyncFunctionBody }
  1. Return FunctionBodyContainsUseStrict of AsyncFunctionBody.

15.9.3 Runtime Semantics: EvaluateAsyncConciseBody

With parameters functionObject and argumentsList (a List).

AsyncConciseBody : ExpressionBody
  1. Let promiseCapability be ! NewPromiseCapability(%Promise%).
  2. Let declResult be FunctionDeclarationInstantiation(functionObject, argumentsList).
  3. If declResult is not an abrupt completion, then
    1. Perform ! AsyncFunctionStart(promiseCapability, ExpressionBody).
  4. Else,
    1. Perform ! Call(promiseCapability.[[Reject]], undefined, « declResult.[[Value]] »).
  5. Return Completion { [[Type]]: return, [[Value]]: promiseCapability.[[Promise]], [[Target]]: empty }.

15.9.4 Runtime Semantics: InstantiateAsyncArrowFunctionExpression

With optional parameter name.

AsyncArrowFunction : async AsyncArrowBindingIdentifier => AsyncConciseBody
  1. If name is not present, set name to "".
  2. Let scope be the LexicalEnvironment of the running execution context.
  3. Let privateScope be the running execution context's PrivateEnvironment.
  4. Let sourceText be the source text matched by AsyncArrowFunction.
  5. Let parameters be AsyncArrowBindingIdentifier.
  6. Let closure be ! OrdinaryFunctionCreate(%AsyncFunction.prototype%, sourceText, parameters, AsyncConciseBody, lexical-this, scope, privateScope).
  7. Perform SetFunctionName(closure, name).
  8. Return closure.
AsyncArrowFunction : CoverCallExpressionAndAsyncArrowHead => AsyncConciseBody
  1. If name is not present, set name to "".
  2. Let scope be the LexicalEnvironment of the running execution context.
  3. Let privateScope be the running execution context's PrivateEnvironment.
  4. Let sourceText be the source text matched by AsyncArrowFunction.
  5. Let head be the AsyncArrowHead that is covered by CoverCallExpressionAndAsyncArrowHead.
  6. Let parameters be the ArrowFormalParameters of head.
  7. Let closure be ! OrdinaryFunctionCreate(%AsyncFunction.prototype%, sourceText, parameters, AsyncConciseBody, lexical-this, scope, privateScope).
  8. Perform SetFunctionName(closure, name).
  9. Return closure.

15.9.5 Runtime Semantics: Evaluation

AsyncArrowFunction : async AsyncArrowBindingIdentifier => AsyncConciseBody CoverCallExpressionAndAsyncArrowHead => AsyncConciseBody
  1. Return InstantiateAsyncArrowFunctionExpression of AsyncArrowFunction.

15.10 Tail Position Calls

15.10.1 Static Semantics: IsInTailPosition ( call )

The abstract operation IsInTailPosition takes argument call (a Parse Node). It performs the following steps when called:

  1. If the source code matching call is non-strict code, return false.
  2. If call is not contained within a FunctionBody, ConciseBody, or AsyncConciseBody, return false.
  3. Let body be the FunctionBody, ConciseBody, or AsyncConciseBody that most closely contains call.
  4. If body is the FunctionBody of a GeneratorBody, return false.
  5. If body is the FunctionBody of an AsyncFunctionBody, return false.
  6. If body is the FunctionBody of an AsyncGeneratorBody, return false.
  7. If body is an AsyncConciseBody, return false.
  8. Return the result of HasCallInTailPosition of body with argument call.
Note

Tail Position calls are only defined in strict mode code because of a common non-standard language extension (see 10.2.4) that enables observation of the chain of caller contexts.

15.10.2 Static Semantics: HasCallInTailPosition

With parameter call.

Note

call is a Parse Node that represents a specific range of source text. When the following algorithms compare call to another Parse Node, it is a test of whether they represent the same source text.

15.10.2.1 Statement Rules

StatementList : StatementList StatementListItem
  1. Let has be HasCallInTailPosition of StatementList with argument call.
  2. If has is true, return true.
  3. Return HasCallInTailPosition of StatementListItem with argument call.
FunctionStatementList : [empty] StatementListItem : Declaration Statement : VariableStatement EmptyStatement ExpressionStatement ContinueStatement BreakStatement ThrowStatement DebuggerStatement Block : { } ReturnStatement : return ; LabelledItem : FunctionDeclaration ForInOfStatement : for ( LeftHandSideExpression of AssignmentExpression ) Statement for ( var ForBinding of AssignmentExpression ) Statement for ( ForDeclaration of AssignmentExpression ) Statement CaseBlock : { }
  1. Return false.
IfStatement : if ( Expression ) Statement else Statement
  1. Let has be HasCallInTailPosition of the first Statement with argument call.
  2. If has is true, return true.
  3. Return HasCallInTailPosition of the second Statement with argument call.
IfStatement : if ( Expression ) Statement DoWhileStatement : do Statement while ( Expression ) ; WhileStatement : while ( Expression ) Statement ForStatement : for ( Expressionopt ; Expressionopt ; Expressionopt ) Statement for ( var VariableDeclarationList ; Expressionopt ; Expressionopt ) Statement for ( LexicalDeclaration Expressionopt ; Expressionopt ) Statement ForInOfStatement : for ( LeftHandSideExpression in Expression ) Statement for ( var ForBinding in Expression ) Statement for ( ForDeclaration in Expression ) Statement for await ( LeftHandSideExpression of AssignmentExpression ) Statement for await ( var ForBinding of AssignmentExpression ) Statement for await ( ForDeclaration of AssignmentExpression ) Statement WithStatement : with ( Expression ) Statement
  1. Return HasCallInTailPosition of Statement with argument call.
LabelledStatement : LabelIdentifier : LabelledItem
  1. Return HasCallInTailPosition of LabelledItem with argument call.
ReturnStatement : return Expression ;
  1. Return HasCallInTailPosition of Expression with argument call.
SwitchStatement : switch ( Expression ) CaseBlock
  1. Return HasCallInTailPosition of CaseBlock with argument call.
CaseBlock : { CaseClausesopt DefaultClause CaseClausesopt }
  1. Let has be false.
  2. If the first CaseClauses is present, let has be HasCallInTailPosition of the first CaseClauses with argument call.
  3. If has is true, return true.
  4. Let has be HasCallInTailPosition of DefaultClause with argument call.
  5. If has is true, return true.
  6. If the second CaseClauses is present, let has be HasCallInTailPosition of the second CaseClauses with argument call.
  7. Return has.
CaseClauses : CaseClauses CaseClause
  1. Let has be HasCallInTailPosition of CaseClauses with argument call.
  2. If has is true, return true.
  3. Return HasCallInTailPosition of CaseClause with argument call.
CaseClause : case Expression : StatementListopt DefaultClause : default : StatementListopt
  1. If StatementList is present, return HasCallInTailPosition of StatementList with argument call.
  2. Return false.
TryStatement : try Block Catch
  1. Return HasCallInTailPosition of Catch with argument call.
TryStatement : try Block Finally TryStatement : try Block Catch Finally
  1. Return HasCallInTailPosition of Finally with argument call.
Catch : catch ( CatchParameter ) Block
  1. Return HasCallInTailPosition of Block with argument call.

15.10.2.2 Expression Rules

Note

A potential tail position call that is immediately followed by return GetValue of the call result is also a possible tail position call. A function call cannot return a Reference Record, so such a GetValue operation will always return the same value as the actual function call result.

AssignmentExpression : YieldExpression ArrowFunction AsyncArrowFunction LeftHandSideExpression = AssignmentExpression LeftHandSideExpression AssignmentOperator AssignmentExpression LeftHandSideExpression &&= AssignmentExpression LeftHandSideExpression ||= AssignmentExpression LeftHandSideExpression ??= AssignmentExpression BitwiseANDExpression : BitwiseANDExpression & EqualityExpression BitwiseXORExpression : BitwiseXORExpression ^ BitwiseANDExpression BitwiseORExpression : BitwiseORExpression | BitwiseXORExpression EqualityExpression : EqualityExpression == RelationalExpression EqualityExpression != RelationalExpression EqualityExpression === RelationalExpression EqualityExpression !== RelationalExpression RelationalExpression : RelationalExpression < ShiftExpression RelationalExpression > ShiftExpression RelationalExpression <= ShiftExpression RelationalExpression >= ShiftExpression RelationalExpression instanceof ShiftExpression RelationalExpression in ShiftExpression PrivateIdentifier in ShiftExpression ShiftExpression : ShiftExpression << AdditiveExpression ShiftExpression >> AdditiveExpression ShiftExpression >>> AdditiveExpression AdditiveExpression : AdditiveExpression + MultiplicativeExpression AdditiveExpression - MultiplicativeExpression MultiplicativeExpression : MultiplicativeExpression MultiplicativeOperator ExponentiationExpression ExponentiationExpression : UpdateExpression ** ExponentiationExpression UpdateExpression : LeftHandSideExpression ++ LeftHandSideExpression -- ++ UnaryExpression -- UnaryExpression UnaryExpression : delete UnaryExpression void UnaryExpression typeof UnaryExpression + UnaryExpression - UnaryExpression ~ UnaryExpression ! UnaryExpression AwaitExpression CallExpression : SuperCall CallExpression [ Expression ] CallExpression . IdentifierName CallExpression . PrivateIdentifier NewExpression : new NewExpression MemberExpression : MemberExpression [ Expression ] MemberExpression . IdentifierName SuperProperty MetaProperty new MemberExpression Arguments MemberExpression . PrivateIdentifier PrimaryExpression : this IdentifierReference Literal ArrayLiteral ObjectLiteral FunctionExpression ClassExpression GeneratorExpression AsyncFunctionExpression AsyncGeneratorExpression RegularExpressionLiteral TemplateLiteral
  1. Return false.
Expression : AssignmentExpression Expression , AssignmentExpression
  1. Return HasCallInTailPosition of AssignmentExpression with argument call.
ConditionalExpression : ShortCircuitExpression ? AssignmentExpression : AssignmentExpression
  1. Let has be HasCallInTailPosition of the first AssignmentExpression with argument call.
  2. If has is true, return true.
  3. Return HasCallInTailPosition of the second AssignmentExpression with argument call.
LogicalANDExpression : LogicalANDExpression && BitwiseORExpression
  1. Return HasCallInTailPosition of BitwiseORExpression with argument call.
LogicalORExpression : LogicalORExpression || LogicalANDExpression
  1. Return HasCallInTailPosition of LogicalANDExpression with argument call.
CoalesceExpression : CoalesceExpressionHead ?? BitwiseORExpression
  1. Return HasCallInTailPosition of BitwiseORExpression with argument call.
CallExpression : CoverCallExpressionAndAsyncArrowHead CallExpression Arguments CallExpression TemplateLiteral
  1. If this CallExpression is call, return true.
  2. Return false.
OptionalExpression : MemberExpression OptionalChain CallExpression OptionalChain OptionalExpression OptionalChain
  1. Return HasCallInTailPosition of OptionalChain with argument call.
OptionalChain : ?. [ Expression ] ?. IdentifierName ?. PrivateIdentifier OptionalChain [ Expression ] OptionalChain . IdentifierName OptionalChain . PrivateIdentifier
  1. Return false.
OptionalChain : ?. Arguments OptionalChain Arguments
  1. If this OptionalChain is call, return true.
  2. Return false.
MemberExpression : MemberExpression TemplateLiteral
  1. If this MemberExpression is call, return true.
  2. Return false.
PrimaryExpression : CoverParenthesizedExpressionAndArrowParameterList
  1. Let expr be the ParenthesizedExpression that is covered by CoverParenthesizedExpressionAndArrowParameterList.
  2. Return HasCallInTailPosition of expr with argument call.
ParenthesizedExpression : ( Expression )
  1. Return HasCallInTailPosition of Expression with argument call.

15.10.3 PrepareForTailCall ( )

The abstract operation PrepareForTailCall takes no arguments. It performs the following steps when called:

  1. Assert: The current execution context will not subsequently be used for the evaluation of any ECMAScript code or built-in functions. The invocation of Call subsequent to the invocation of this abstract operation will create and push a new execution context before performing any such evaluation.
  2. Discard all resources associated with the current execution context.

A tail position call must either release any transient internal resources associated with the currently executing function execution context before invoking the target function or reuse those resources in support of the target function.

Note

For example, a tail position call should only grow an implementation's activation record stack by the amount that the size of the target function's activation record exceeds the size of the calling function's activation record. If the target function's activation record is smaller, then the total size of the stack should decrease.