# 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

- It is a Syntax Error if the BoundNames of FormalParameters contains any duplicate elements.

FormalParameters : FormalParameterList

- It is a Syntax Error if IsSimpleParameterList of FormalParameterList is false and the BoundNames of FormalParameterList contains any duplicate elements.

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

The syntax-directed operation ContainsExpression takes no arguments and returns a Boolean. It is defined piecewise over the following productions:

ObjectBindingPattern : { } { BindingRestProperty }

1. Return false.

ObjectBindingPattern : { BindingPropertyList , BindingRestProperty }

1. Return ContainsExpression of BindingPropertyList.

ArrayBindingPattern : [ Elision opt ]

1. Return false.

ArrayBindingPattern : [ Elision opt BindingRestElement ]

1. Return ContainsExpression of BindingRestElement.

ArrayBindingPattern : [ BindingElementList , Elision opt ]

1. Return ContainsExpression of BindingElementList.

ArrayBindingPattern : [ BindingElementList , Elision opt 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 : Elision opt 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

The syntax-directed operation IsSimpleParameterList takes no arguments and returns a Boolean. It is defined piecewise over the following productions:

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

The syntax-directed operation HasInitializer takes no arguments and returns a Boolean. It is defined piecewise over the following productions:

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

The syntax-directed operation ExpectedArgumentCount takes no arguments and returns a non-negative integer. It is defined piecewise over the following productions:

FormalParameters : [empty] FunctionRestParameter

1. Return 0.

FormalParameters : FormalParameterList , FunctionRestParameter

1. Return the 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 the 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 the 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 BindingIdentifier opt ( FormalParameters ) { FunctionBody }

- If IsStrict(FormalParameters) is true, the Early Error rules for UniqueFormalParameters : FormalParameters are applied.
- If BindingIdentifier is present and IsStrict(BindingIdentifier) is true, it is a Syntax Error if the StringValue of BindingIdentifier is either "eval" or "arguments".
- It is a Syntax Error if FunctionBodyContainsUseStrict of FunctionBody is true and IsSimpleParameterList of FormalParameters is false.
- It is a Syntax Error if any element of the BoundNames of FormalParameters also occurs in the LexicallyDeclaredNames of FunctionBody.
- It is a Syntax Error if FormalParameters Contains SuperProperty is true.
- It is a Syntax Error if FunctionBody Contains SuperProperty is true.
- It is a Syntax Error if FormalParameters Contains SuperCall is true.
- It is a Syntax Error if FunctionBody Contains SuperCall is true.

Note

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

FunctionBody : FunctionStatementList

- It is a Syntax Error if the LexicallyDeclaredNames of FunctionStatementList contains any duplicate entries.
- It is a Syntax Error if any element of the LexicallyDeclaredNames of FunctionStatementList also occurs in the VarDeclaredNames of FunctionStatementList.
- It is a Syntax Error if ContainsDuplicateLabels of FunctionStatementList with argument « » is true.
- It is a Syntax Error if ContainsUndefinedBreakTarget of FunctionStatementList with argument « » is true.
- It is a Syntax Error if ContainsUndefinedContinueTarget of FunctionStatementList with arguments « » and « » is true.

# 15.2.2 Static Semantics: FunctionBodyContainsUseStrict

The syntax-directed operation FunctionBodyContainsUseStrict takes no arguments and returns a Boolean. It is defined piecewise over the following productions:

FunctionBody : FunctionStatementList

1. If the Directive Prologue of FunctionBody contains a Use Strict Directive, return true.
2. Return false.

# 15.2.3 Runtime Semantics: EvaluateFunctionBody

The syntax-directed operation EvaluateFunctionBody takes arguments functionObject (an ECMAScript function object) and argumentsList (a List of ECMAScript language values) and returns a return completion or a throw completion. It is defined piecewise over the following productions:

FunctionBody : FunctionStatementList

1. Perform ? FunctionDeclarationInstantiation(functionObject, argumentsList).
2. Perform ? Evaluation of FunctionStatementList.
3. NOTE: If the previous step resulted in a normal completion, then evaluation finished by proceeding past the end of the FunctionStatementList.
4. Return ReturnCompletion(undefined).

# 15.2.4 Runtime Semantics: InstantiateOrdinaryFunctionObject

The syntax-directed operation InstantiateOrdinaryFunctionObject takes arguments env (an Environment Record) and privateEnv (a PrivateEnvironment Record or null) and returns an ECMAScript function object. It is defined piecewise over the following productions:

FunctionDeclaration : function BindingIdentifier ( FormalParameters ) { FunctionBody }

1. Let name be the 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, env, privateEnv).
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, env, privateEnv).
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

The syntax-directed operation InstantiateOrdinaryFunctionExpression takes optional argument name (a property key or a Private Name) and returns an ECMAScript function object. It is defined piecewise over the following productions:

FunctionExpression : function ( FormalParameters ) { FunctionBody }

1. If name is not present, set name to "".
2. Let env be the LexicalEnvironment of the running execution context.
3. Let privateEnv 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, env, privateEnv).
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 the StringValue of BindingIdentifier.
3. Let outerEnv be the running execution context's LexicalEnvironment.
4. Let funcEnv be NewDeclarativeEnvironment(outerEnv).
5. Perform ! funcEnv.CreateImmutableBinding(name, false).
6. Let privateEnv 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, privateEnv).
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 empty.

Note 1

An alternative semantics is provided by Block-Level Function Declarations Web Legacy Compatibility Semantics at step 32.a.i.2.c of FunctionDeclarationInstantiation, step 12.b.ii.2.a.ii.iii of GlobalDeclarationInstantiation, and step 13.b.ii.7.b of EvalDeclarationInstantiation.

FunctionDeclaration : function ( FormalParameters ) { FunctionBody }

1. Return empty.

FunctionExpression : function BindingIdentifier opt ( 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 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

- It is a Syntax Error if ArrowParameters Contains YieldExpression is true.
- It is a Syntax Error if ArrowParameters Contains AwaitExpression is true.
- It is a Syntax Error if ConciseBodyContainsUseStrict of ConciseBody is true and IsSimpleParameterList of ArrowParameters is false.
- It is a Syntax Error if any element of the BoundNames of ArrowParameters also occurs in the LexicallyDeclaredNames of ConciseBody.

ArrowParameters : CoverParenthesizedExpressionAndArrowParameterList

- CoverParenthesizedExpressionAndArrowParameterList must cover an ArrowFormalParameters.

# 15.3.2 Static Semantics: ConciseBodyContainsUseStrict

The syntax-directed operation ConciseBodyContainsUseStrict takes no arguments and returns a Boolean. It is defined piecewise over the following productions:

ConciseBody : ExpressionBody

1. Return false.

ConciseBody : { FunctionBody }

1. Return FunctionBodyContainsUseStrict of FunctionBody.

# 15.3.3 Runtime Semantics: EvaluateConciseBody

The syntax-directed operation EvaluateConciseBody takes arguments functionObject (an ECMAScript function object) and argumentsList (a List of ECMAScript language values) and returns a return completion or a throw completion. It is defined piecewise over the following productions:

ConciseBody : ExpressionBody

1. Perform ? FunctionDeclarationInstantiation(functionObject, argumentsList).
2. Return ? Evaluation of ExpressionBody.

# 15.3.4 Runtime Semantics: InstantiateArrowFunctionExpression

The syntax-directed operation InstantiateArrowFunctionExpression takes optional argument name (a property key or a Private Name) and returns an ECMAScript function object. It is defined piecewise over the following productions:

ArrowFunction : ArrowParameters => ConciseBody

1. If name is not present, set name to "".
2. Let env be the LexicalEnvironment of the running execution context.
3. Let privateEnv 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, env, privateEnv).
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 env 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 ? Evaluation of AssignmentExpression.
2. Let exprValue be ? GetValue(exprRef).
3. Return ReturnCompletion(exprValue).

# 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 }

- It is a Syntax Error if FunctionBodyContainsUseStrict of FunctionBody is true and IsSimpleParameterList of UniqueFormalParameters is false.
- It is a Syntax Error if any element of the BoundNames of UniqueFormalParameters also occurs in the LexicallyDeclaredNames of FunctionBody.

MethodDefinition : set ClassElementName ( PropertySetParameterList ) { FunctionBody }

- It is a Syntax Error if the BoundNames of PropertySetParameterList contains any duplicate elements.
- It is a Syntax Error if FunctionBodyContainsUseStrict of FunctionBody is true and IsSimpleParameterList of PropertySetParameterList is false.
- It is a Syntax Error if any element of the BoundNames of PropertySetParameterList also occurs in the LexicallyDeclaredNames of FunctionBody.

# 15.4.2 Static Semantics: HasDirectSuper

The syntax-directed operation HasDirectSuper takes no arguments and returns a Boolean. It is defined piecewise over the following productions:

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

The syntax-directed operation SpecialMethod takes no arguments and returns a Boolean. It is defined piecewise over the following productions:

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

The syntax-directed operation DefineMethod takes argument object (an Object) and optional argument functionPrototype (an Object) and returns either a normal completion containing a Record with fields [[Key]] (a property key) and [[Closure]] (an ECMAScript function object) or an abrupt completion. It is defined piecewise over the following productions:

MethodDefinition : ClassElementName ( UniqueFormalParameters ) { FunctionBody }

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

# 15.4.5 Runtime Semantics: MethodDefinitionEvaluation

The syntax-directed operation MethodDefinitionEvaluation takes arguments object (an Object) and enumerable (a Boolean) and returns either a normal completion containing either a PrivateElement or unused, or an abrupt completion. It is defined piecewise over the following productions:

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 ? Evaluation of ClassElementName.
2. Let env be the running execution context's LexicalEnvironment.
3. Let privateEnv be the running execution context's PrivateEnvironment.
4. Let sourceText be the source text matched by MethodDefinition.
5. Let formalParameterList be an instance of the production FormalParameters : [empty] .
6. Let closure be OrdinaryFunctionCreate(%Function.prototype%, sourceText, formalParameterList, FunctionBody, non-lexical-this, env, privateEnv).
7. Perform MakeMethod(closure, object).
8. Perform SetFunctionName(closure, propKey, "get").
9. If propKey is a Private Name, then
   1. Return PrivateElement { [[Key]]: propKey, [[Kind]]: accessor, [[Get]]: closure, [[Set]]: undefined }.
10. Let desc be the PropertyDescriptor { [[Get]]: closure, [[Enumerable]]: enumerable, [[Configurable]]: true }.
11. Perform ? DefinePropertyOrThrow(object, propKey, desc).
12. Return unused.

MethodDefinition : set ClassElementName ( PropertySetParameterList ) { FunctionBody }

1. Let propKey be ? Evaluation of ClassElementName.
2. Let env be the running execution context's LexicalEnvironment.
3. Let privateEnv be the running execution context's PrivateEnvironment.
4. Let sourceText be the source text matched by MethodDefinition.
5. Let closure be OrdinaryFunctionCreate(%Function.prototype%, sourceText, PropertySetParameterList, FunctionBody, non-lexical-this, env, privateEnv).
6. Perform MakeMethod(closure, object).
7. Perform SetFunctionName(closure, propKey, "set").
8. If propKey is a Private Name, then
   1. Return PrivateElement { [[Key]]: propKey, [[Kind]]: accessor, [[Get]]: undefined, [[Set]]: closure }.
9. Let desc be the PropertyDescriptor { [[Set]]: closure, [[Enumerable]]: enumerable, [[Configurable]]: true }.
10. Perform ? DefinePropertyOrThrow(object, propKey, desc).
11. Return unused.

GeneratorMethod : * ClassElementName ( UniqueFormalParameters ) { GeneratorBody }

1. Let propKey be ? Evaluation of ClassElementName.
2. Let env be the running execution context's LexicalEnvironment.
3. Let privateEnv be the running execution context's PrivateEnvironment.
4. Let sourceText be the source text matched by GeneratorMethod.
5. Let closure be OrdinaryFunctionCreate(%GeneratorFunction.prototype%, sourceText, UniqueFormalParameters, GeneratorBody, non-lexical-this, env, privateEnv).
6. Perform MakeMethod(closure, object).
7. Perform SetFunctionName(closure, propKey).
8. Let prototype be OrdinaryObjectCreate(%GeneratorPrototype%).
9. Perform ! DefinePropertyOrThrow(closure, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }).
10. Return ? DefineMethodProperty(object, propKey, closure, enumerable).

AsyncGeneratorMethod : async * ClassElementName ( UniqueFormalParameters ) { AsyncGeneratorBody }

1. Let propKey be ? Evaluation of ClassElementName.
2. Let env be the running execution context's LexicalEnvironment.
3. Let privateEnv be the running execution context's PrivateEnvironment.
4. Let sourceText be the source text matched by AsyncGeneratorMethod.
5. Let closure be OrdinaryFunctionCreate(%AsyncGeneratorFunction.prototype%, sourceText, UniqueFormalParameters, AsyncGeneratorBody, non-lexical-this, env, privateEnv).
6. Perform MakeMethod(closure, object).
7. Perform SetFunctionName(closure, propKey).
8. Let prototype be OrdinaryObjectCreate(%AsyncGeneratorPrototype%).
9. Perform ! DefinePropertyOrThrow(closure, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }).
10. Return ? DefineMethodProperty(object, propKey, closure, enumerable).

AsyncMethod : async ClassElementName ( UniqueFormalParameters ) { AsyncFunctionBody }

1. Let propKey be ? Evaluation of ClassElementName.
2. Let env be the LexicalEnvironment of the running execution context.
3. Let privateEnv be the running execution context's PrivateEnvironment.
4. Let sourceText be the source text matched by AsyncMethod.
5. Let closure be OrdinaryFunctionCreate(%AsyncFunction.prototype%, sourceText, UniqueFormalParameters, AsyncFunctionBody, non-lexical-this, env, privateEnv).
6. Perform MakeMethod(closure, object).
7. Perform SetFunctionName(closure, propKey).
8. 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 }

- It is a Syntax Error if HasDirectSuper of GeneratorMethod is true.
- It is a Syntax Error if UniqueFormalParameters Contains YieldExpression is true.
- It is a Syntax Error if FunctionBodyContainsUseStrict of GeneratorBody is true and IsSimpleParameterList of UniqueFormalParameters is false.
- It is a Syntax Error if any element of the BoundNames of UniqueFormalParameters also occurs in the LexicallyDeclaredNames of GeneratorBody.

GeneratorDeclaration : function * BindingIdentifier ( FormalParameters ) { GeneratorBody } function * ( FormalParameters ) { GeneratorBody } GeneratorExpression : function * BindingIdentifier opt ( FormalParameters ) { GeneratorBody }

- If IsStrict(FormalParameters) is true, the Early Error rules for UniqueFormalParameters : FormalParameters are applied.
- If BindingIdentifier is present and IsStrict(BindingIdentifier) is true, it is a Syntax Error if the StringValue of BindingIdentifier is either "eval" or "arguments".
- It is a Syntax Error if FunctionBodyContainsUseStrict of GeneratorBody is true and IsSimpleParameterList of FormalParameters is false.
- It is a Syntax Error if any element of the BoundNames of FormalParameters also occurs in the LexicallyDeclaredNames of GeneratorBody.
- It is a Syntax Error if FormalParameters Contains YieldExpression is true.
- It is a Syntax Error if FormalParameters Contains SuperProperty is true.
- It is a Syntax Error if GeneratorBody Contains SuperProperty is true.
- It is a Syntax Error if FormalParameters Contains SuperCall is true.
- It is a Syntax Error if GeneratorBody Contains SuperCall is true.

# 15.5.2 Runtime Semantics: EvaluateGeneratorBody

The syntax-directed operation EvaluateGeneratorBody takes arguments functionObject (an ECMAScript function object) and argumentsList (a List of ECMAScript language values) and returns a throw completion or a return completion. It is defined piecewise over the following productions:

GeneratorBody : FunctionBody

1. Perform ? FunctionDeclarationInstantiation(functionObject, argumentsList).
2. Let G be ? OrdinaryCreateFromConstructor(functionObject, "%GeneratorPrototype%", « [[GeneratorState]], [[GeneratorContext]], [[GeneratorBrand]] »).
3. Set G.[[GeneratorBrand]] to empty.
4. Set G.[[GeneratorState]] to suspended-start.
5. Perform GeneratorStart(G, FunctionBody).
6. Return ReturnCompletion(G).

# 15.5.3 Runtime Semantics: InstantiateGeneratorFunctionObject

The syntax-directed operation InstantiateGeneratorFunctionObject takes arguments env (an Environment Record) and privateEnv (a PrivateEnvironment Record or null) and returns an ECMAScript function object. It is defined piecewise over the following productions:

GeneratorDeclaration : function * BindingIdentifier ( FormalParameters ) { GeneratorBody }

1. Let name be the 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, env, privateEnv).
4. Perform SetFunctionName(F, name).
5. Let prototype be OrdinaryObjectCreate(%GeneratorPrototype%).
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, env, privateEnv).
3. Perform SetFunctionName(F, "default").
4. Let prototype be OrdinaryObjectCreate(%GeneratorPrototype%).
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

The syntax-directed operation InstantiateGeneratorFunctionExpression takes optional argument name (a property key or a Private Name) and returns an ECMAScript function object. It is defined piecewise over the following productions:

GeneratorExpression : function * ( FormalParameters ) { GeneratorBody }

1. If name is not present, set name to "".
2. Let env be the LexicalEnvironment of the running execution context.
3. Let privateEnv 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, env, privateEnv).
6. Perform SetFunctionName(closure, name).
7. Let prototype be OrdinaryObjectCreate(%GeneratorPrototype%).
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 the StringValue of BindingIdentifier.
3. Let outerEnv be the running execution context's LexicalEnvironment.
4. Let funcEnv be NewDeclarativeEnvironment(outerEnv).
5. Perform ! funcEnv.CreateImmutableBinding(name, false).
6. Let privateEnv 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, privateEnv).
9. Perform SetFunctionName(closure, name).
10. Let prototype be OrdinaryObjectCreate(%GeneratorPrototype%).
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 * BindingIdentifier opt ( FormalParameters ) { GeneratorBody }

1. Return InstantiateGeneratorFunctionExpression of GeneratorExpression.

YieldExpression : yield

1. Return ? Yield(undefined).

YieldExpression : yield AssignmentExpression

1. Let exprRef be ? Evaluation of AssignmentExpression.
2. Let value be ? GetValue(exprRef).
3. Return ? Yield(value).

YieldExpression : yield * AssignmentExpression

1. Let generatorKind be GetGeneratorKind().
2. Assert: generatorKind is either sync or async.
3. Let exprRef be ? Evaluation of AssignmentExpression.
4. Let value be ? GetValue(exprRef).
5. Let iteratorRecord be ? GetIterator(value, generatorKind).
6. Let iterator be iteratorRecord.[[Iterator]].
7. Let received be NormalCompletion(undefined).
8. Repeat,
   1. If received is a normal completion, then
      1. Let innerResult be ? Call(iteratorRecord.[[NextMethod]], iteratorRecord.[[Iterator]], « received.[[Value]] »).
      2. If generatorKind is async, set innerResult to ? Await(innerResult).
      3. If innerResult is not an 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 Completion(AsyncGeneratorYield(? IteratorValue(innerResult))).
      7. Else, set received to Completion(GeneratorYield(innerResult)).
   2. Else if received is a throw completion, 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 innerResult is not an 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 Completion(AsyncGeneratorYield(? IteratorValue(innerResult))).
         8. Else, set received to Completion(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 NormalCompletion(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 is a return completion.
      2. Let return be ? GetMethod(iterator, "return").
      3. If return is undefined, then
         1. Let receivedValue be received.[[Value]].
         2. If generatorKind is async, then
            1. Set receivedValue to ? Await(receivedValue).
         3. Return ReturnCompletion(receivedValue).
      4. Let innerReturnResult be ? Call(return, iterator, « received.[[Value]] »).
      5. If generatorKind is async, set innerReturnResult to ? Await(innerReturnResult).
      6. If innerReturnResult is not an Object, throw a TypeError exception.
      7. Let done be ? IteratorComplete(innerReturnResult).
      8. If done is true, then
         1. Let returnedValue be ? IteratorValue(innerReturnResult).
         2. Return ReturnCompletion(returnedValue).
      9. If generatorKind is async, set received to Completion(AsyncGeneratorYield(? IteratorValue(innerReturnResult))).
      10. Else, set received to Completion(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 }

- It is a Syntax Error if HasDirectSuper of AsyncGeneratorMethod is true.
- It is a Syntax Error if UniqueFormalParameters Contains YieldExpression is true.
- It is a Syntax Error if UniqueFormalParameters Contains AwaitExpression is true.
- It is a Syntax Error if FunctionBodyContainsUseStrict of AsyncGeneratorBody is true and IsSimpleParameterList of UniqueFormalParameters is false.
- It is a Syntax Error if any element of the BoundNames of UniqueFormalParameters also occurs in the LexicallyDeclaredNames of AsyncGeneratorBody.

AsyncGeneratorDeclaration : async function * BindingIdentifier ( FormalParameters ) { AsyncGeneratorBody } async function * ( FormalParameters ) { AsyncGeneratorBody } AsyncGeneratorExpression : async function * BindingIdentifier opt ( FormalParameters ) { AsyncGeneratorBody }

- If IsStrict(FormalParameters) is true, the Early Error rules for UniqueFormalParameters : FormalParameters are applied.
- If BindingIdentifier is present and IsStrict(BindingIdentifier) is true, it is a Syntax Error if the StringValue of BindingIdentifier is either "eval" or "arguments".
- It is a Syntax Error if FunctionBodyContainsUseStrict of AsyncGeneratorBody is true and IsSimpleParameterList of FormalParameters is false.
- It is a Syntax Error if any element of the BoundNames of FormalParameters also occurs in the LexicallyDeclaredNames of AsyncGeneratorBody.
- It is a Syntax Error if FormalParameters Contains YieldExpression is true.
- It is a Syntax Error if FormalParameters Contains AwaitExpression is true.
- It is a Syntax Error if FormalParameters Contains SuperProperty is true.
- It is a Syntax Error if AsyncGeneratorBody Contains SuperProperty is true.
- It is a Syntax Error if FormalParameters Contains SuperCall is true.
- It is a Syntax Error if AsyncGeneratorBody Contains SuperCall is true.

# 15.6.2 Runtime Semantics: EvaluateAsyncGeneratorBody

The syntax-directed operation EvaluateAsyncGeneratorBody takes arguments functionObject (an ECMAScript function object) and argumentsList (a List of ECMAScript language values) and returns a throw completion or a return completion. It is defined piecewise over the following productions:

AsyncGeneratorBody : FunctionBody

1. Perform ? FunctionDeclarationInstantiation(functionObject, argumentsList).
2. Let generator be ? OrdinaryCreateFromConstructor(functionObject, "%AsyncGeneratorPrototype%", « [[AsyncGeneratorState]], [[AsyncGeneratorContext]], [[AsyncGeneratorQueue]], [[GeneratorBrand]] »).
3. Set generator.[[GeneratorBrand]] to empty.
4. Set generator.[[AsyncGeneratorState]] to suspended-start.
5. Perform AsyncGeneratorStart(generator, FunctionBody).
6. Return ReturnCompletion(generator).

# 15.6.3 Runtime Semantics: InstantiateAsyncGeneratorFunctionObject

The syntax-directed operation InstantiateAsyncGeneratorFunctionObject takes arguments env (an Environment Record) and privateEnv (a PrivateEnvironment Record or null) and returns an ECMAScript function object. It is defined piecewise over the following productions:

AsyncGeneratorDeclaration : async function * BindingIdentifier ( FormalParameters ) { AsyncGeneratorBody }

1. Let name be the 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, env, privateEnv).
4. Perform SetFunctionName(F, name).
5. Let prototype be OrdinaryObjectCreate(%AsyncGeneratorPrototype%).
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, env, privateEnv).
3. Perform SetFunctionName(F, "default").
4. Let prototype be OrdinaryObjectCreate(%AsyncGeneratorPrototype%).
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

The syntax-directed operation InstantiateAsyncGeneratorFunctionExpression takes optional argument name (a property key or a Private Name) and returns an ECMAScript function object. It is defined piecewise over the following productions:

AsyncGeneratorExpression : async function * ( FormalParameters ) { AsyncGeneratorBody }

1. If name is not present, set name to "".
2. Let env be the LexicalEnvironment of the running execution context.
3. Let privateEnv 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, env, privateEnv).
6. Perform SetFunctionName(closure, name).
7. Let prototype be OrdinaryObjectCreate(%AsyncGeneratorPrototype%).
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 the StringValue of BindingIdentifier.
3. Let outerEnv be the running execution context's LexicalEnvironment.
4. Let funcEnv be NewDeclarativeEnvironment(outerEnv).
5. Perform ! funcEnv.CreateImmutableBinding(name, false).
6. Let privateEnv 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, privateEnv).
9. Perform SetFunctionName(closure, name).
10. Let prototype be OrdinaryObjectCreate(%AsyncGeneratorPrototype%).
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 * BindingIdentifier opt ( 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 : ClassHeritage opt { ClassBody }

- It is a Syntax Error if ClassHeritage is not present and the following algorithm returns true:

  1. Let constructor be the ConstructorMethod of ClassBody.
  2. If constructor is empty, return false.
  3. Return HasDirectSuper of constructor.

ClassBody : ClassElementList

- It is a Syntax Error if the PrototypePropertyNameList of ClassElementList contains more than one occurrence of "constructor".
- It is a Syntax Error if the PrivateBoundIdentifiers of ClassElementList contains any duplicate entries, unless the name is used once for a getter and once for a setter and in no other entries, and the getter and setter are either both static or both non-static.

ClassElement : MethodDefinition

- It is a Syntax Error if the PropName of MethodDefinition is not "constructor" and HasDirectSuper of MethodDefinition is true.
- It is a Syntax Error if the PropName of MethodDefinition is "constructor" and SpecialMethod of MethodDefinition is true.

ClassElement : static MethodDefinition

- It is a Syntax Error if HasDirectSuper of MethodDefinition is true.
- It is a Syntax Error if the PropName of MethodDefinition is "prototype".

ClassElement : FieldDefinition ;

- It is a Syntax Error if the PropName of FieldDefinition is "constructor".

ClassElement : static FieldDefinition ;

- It is a Syntax Error if the PropName of FieldDefinition is either "prototype" or "constructor".

FieldDefinition : ClassElementName Initializer opt

- It is a Syntax Error if Initializer is present and ContainsArguments of Initializer is true.
- It is a Syntax Error if Initializer is present and Initializer Contains SuperCall is true.

ClassElementName : PrivateIdentifier

- It is a Syntax Error if the StringValue of PrivateIdentifier is "#constructor".

ClassStaticBlockBody : ClassStaticBlockStatementList

- It is a Syntax Error if the LexicallyDeclaredNames of ClassStaticBlockStatementList contains any duplicate entries.
- It is a Syntax Error if any element of the LexicallyDeclaredNames of ClassStaticBlockStatementList also occurs in the VarDeclaredNames of ClassStaticBlockStatementList.
- It is a Syntax Error if ContainsDuplicateLabels of ClassStaticBlockStatementList with argument « » is true.
- It is a Syntax Error if ContainsUndefinedBreakTarget of ClassStaticBlockStatementList with argument « » is true.
- It is a Syntax Error if ContainsUndefinedContinueTarget of ClassStaticBlockStatementList with arguments « » and « » is true.
- It is a Syntax Error if ContainsArguments of ClassStaticBlockStatementList is true.
- It is a Syntax Error if ClassStaticBlockStatementList Contains SuperCall is true.
- It is a Syntax Error if ClassStaticBlockStatementList Contains `await` is true.

# 15.7.2 Static Semantics: ClassElementKind

The syntax-directed operation ClassElementKind takes no arguments and returns constructor-method, non-constructor-method, or empty. It is defined piecewise over the following productions:

ClassElement : MethodDefinition

1. If the PropName of MethodDefinition is "constructor", return constructor-method.
2. Return non-constructor-method.

ClassElement : static MethodDefinition FieldDefinition ; static FieldDefinition ;

1. Return non-constructor-method.

ClassElement : ClassStaticBlock

1. Return non-constructor-method.

ClassElement : ;

1. Return empty.

# 15.7.3 Static Semantics: ConstructorMethod

The syntax-directed operation ConstructorMethod takes no arguments and returns a ClassElement Parse Node or empty. It is defined piecewise over the following productions:

ClassElementList : ClassElement

1. If the ClassElementKind of ClassElement is constructor-method, return ClassElement.
2. Return empty.

ClassElementList : ClassElementList ClassElement

1. Let head be the ConstructorMethod of ClassElementList.
2. If head is not empty, return head.
3. If the ClassElementKind of ClassElement is constructor-method, 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

The syntax-directed operation IsStatic takes no arguments and returns a Boolean. It is defined piecewise over the following productions:

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

The syntax-directed operation NonConstructorElements takes no arguments and returns a List of ClassElement Parse Nodes. It is defined piecewise over the following productions:

ClassElementList : ClassElement

1. If the ClassElementKind of ClassElement is non-constructor-method, then
   1. Return « ClassElement ».
2. Return a new empty List.

ClassElementList : ClassElementList ClassElement

1. Let list be the NonConstructorElements of ClassElementList.
2. If the ClassElementKind of ClassElement is non-constructor-method, then
   1. Append ClassElement to list.
3. Return list.

# 15.7.6 Static Semantics: PrototypePropertyNameList

The syntax-directed operation PrototypePropertyNameList takes no arguments and returns a List of property keys. It is defined piecewise over the following productions:

ClassElementList : ClassElement

1. Let propName be the 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 « propName ».

ClassElementList : ClassElementList ClassElement

1. Let list be the PrototypePropertyNameList of ClassElementList.
2. Let propName be the 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

The syntax-directed operation AllPrivateIdentifiersValid takes argument names (a List of Strings) and returns a Boolean.

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 the 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

The syntax-directed operation PrivateBoundIdentifiers takes no arguments and returns a List of Strings. It is defined piecewise over the following productions:

FieldDefinition : ClassElementName Initializer opt

1. Return the PrivateBoundIdentifiers of ClassElementName.

ClassElementName : PrivateIdentifier

1. Return a List whose sole element is the StringValue of PrivateIdentifier.

ClassElementName : PropertyName ClassElement : ClassStaticBlock ;

1. Return a new empty List.

ClassElementList : ClassElementList ClassElement

1. Let names1 be the PrivateBoundIdentifiers of ClassElementList.
2. Let names2 be the 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 the PrivateBoundIdentifiers of ClassElementName.

# 15.7.9 Static Semantics: ContainsArguments

The syntax-directed operation ContainsArguments takes no arguments and returns a Boolean.

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 BindingIdentifier opt ( FormalParameters ) { FunctionBody } GeneratorDeclaration : function * BindingIdentifier ( FormalParameters ) { GeneratorBody } function * ( FormalParameters ) { GeneratorBody } GeneratorExpression : function * BindingIdentifier opt ( FormalParameters ) { GeneratorBody } AsyncGeneratorDeclaration : async function * BindingIdentifier ( FormalParameters ) { AsyncGeneratorBody } async function * ( FormalParameters ) { AsyncGeneratorBody } AsyncGeneratorExpression : async function * BindingIdentifier opt ( FormalParameters ) { AsyncGeneratorBody } AsyncFunctionDeclaration : async function BindingIdentifier ( FormalParameters ) { AsyncFunctionBody } async function ( FormalParameters ) { AsyncFunctionBody } AsyncFunctionExpression : async function BindingIdentifier opt ( 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

The syntax-directed operation ClassFieldDefinitionEvaluation takes argument homeObject (an Object) and returns either a normal completion containing a ClassFieldDefinition Record or an abrupt completion. It is defined piecewise over the following productions:

FieldDefinition : ClassElementName Initializer opt

1. Let name be ? Evaluation of ClassElementName.
2. If Initializer is present, then
   1. Let formalParameterList be an instance of the production FormalParameters : [empty] .
   2. Let env be the LexicalEnvironment of the running execution context.
   3. Let privateEnv 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, env, privateEnv).
   6. Perform MakeMethod(initializer, homeObject).
   7. Set initializer.[[ClassFieldInitializerName]] to name.
3. Else,
   1. Let initializer be empty.
4. 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

The syntax-directed operation ClassStaticBlockDefinitionEvaluation takes argument homeObject (an Object) and returns a ClassStaticBlockDefinition Record. It is defined piecewise over the following productions:

ClassStaticBlock : static { ClassStaticBlockBody }

1. Let lex be the running execution context's LexicalEnvironment.
2. Let privateEnv 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, privateEnv).
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

The syntax-directed operation EvaluateClassStaticBlockBody takes argument functionObject (an ECMAScript function object) and returns a return completion or a throw completion. It is defined piecewise over the following productions:

ClassStaticBlockBody : ClassStaticBlockStatementList

1. Assert: functionObject is a synthetic function created by ClassStaticBlockDefinitionEvaluation step 5.
2. Perform ! FunctionDeclarationInstantiation(functionObject, « »).
3. Perform ? Evaluation of ClassStaticBlockStatementList.
4. Return ReturnCompletion(undefined).

# 15.7.13 Runtime Semantics: ClassElementEvaluation

The syntax-directed operation ClassElementEvaluation takes argument object (an Object) and returns either a normal completion containing either a ClassFieldDefinition Record, a ClassStaticBlockDefinition Record, a PrivateElement, or unused, or an abrupt completion. It is defined piecewise over the following productions:

ClassElement : FieldDefinition ; static FieldDefinition ;

1. Return ? ClassFieldDefinitionEvaluation of FieldDefinition with argument object.

ClassElement : MethodDefinition static MethodDefinition

1. Return ? MethodDefinitionEvaluation of MethodDefinition with arguments object and false.

ClassElement : ClassStaticBlock

1. Return the ClassStaticBlockDefinitionEvaluation of ClassStaticBlock with argument object.

ClassElement : ;

1. Return unused.

# 15.7.14 Runtime Semantics: ClassDefinitionEvaluation

The syntax-directed operation ClassDefinitionEvaluation takes arguments classBinding (a String or undefined), className (a property key or a Private Name), and sourceText (ECMAScript source text) and returns either a normal completion containing a function object or an abrupt completion.

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.

It is defined piecewise over the following productions:

ClassTail : ClassHeritage opt { ClassBody opt }

1. Let env be the LexicalEnvironment of the running execution context.
2. Let classEnv be NewDeclarativeEnvironment(env).
3. If classBinding is not undefined, then
   1. Perform ! classEnv.CreateImmutableBinding(classBinding, true).
4. Let outerPrivateEnvironment be the running execution context's PrivateEnvironment.
5. Let classPrivateEnvironment be NewPrivateEnvironment(outerPrivateEnvironment).
6. If ClassBody is present, then
   1. For each String dn of the PrivateBoundIdentifiers of ClassBody, do
      1. If classPrivateEnvironment.[[Names]] contains a Private Name pn such that pn.[[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]] is dn.
         2. Append name to classPrivateEnvironment.[[Names]].
7. If ClassHeritage 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 classEnv.
   2. NOTE: The running execution context's PrivateEnvironment is outerPrivateEnvironment when evaluating ClassHeritage.
   3. Let superclassRef be Completion(Evaluation of 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, then
      1. Throw a TypeError exception.
   8. Else,
      1. Let protoParent be ? Get(superclass, "prototype").
      2. If protoParent is not an Object and protoParent is not null, throw a TypeError exception.
      3. Let constructorParent be superclass.
9. Let proto be OrdinaryObjectCreate(protoParent).
10. If ClassBody is not present, let constructor be empty.
11. Else, let constructor be the ConstructorMethod of ClassBody.
12. Set the running execution context's LexicalEnvironment to classEnv.
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 %Symbol.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. Let result be ? Construct(func, args, NewTarget).
       5. Else,
          1. NOTE: This branch behaves similarly to `constructor() {}`.
          2. Let result be ? OrdinaryCreateFromConstructor(NewTarget, "%Object.prototype%").
       6. Perform ? InitializeInstanceElements(result, F).
       7. Return NormalCompletion(result).
    2. Let F be CreateBuiltinFunction(defaultConstructor, 0, className, « [[ConstructorKind]], [[SourceText]], [[PrivateMethods]], [[Fields]] », 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. Set F.[[SourceText]] to sourceText.
17. Perform MakeConstructor(F, false, proto).
18. If ClassHeritage is present, set F.[[ConstructorKind]] to derived.
19. Perform ! DefineMethodProperty(proto, "constructor", F, false).
20. If ClassBody is not present, let elements be a new empty List.
21. Else, let elements be the NonConstructorElements of ClassBody.
22. Let instancePrivateMethods be a new empty List.
23. Let staticPrivateMethods be a new empty List.
24. Let instanceFields be a new empty List.
25. Let staticElements be a new empty List.
26. For each ClassElement e of elements, do
    1. If IsStatic of e is false, then
       1. Let element be Completion(ClassElementEvaluation of e with argument proto).
    2. Else,
       1. Let element be Completion(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 ? element.
    4. Set element to ! element.
    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 pe such that pe.[[Key]] is element.[[Key]], then
          1. Assert: element.[[Kind]] and pe.[[Kind]] are both accessor.
          2. If element.[[Get]] is undefined, then
             1. Let combined be PrivateElement { [[Key]]: element.[[Key]], [[Kind]]: accessor, [[Get]]: pe.[[Get]], [[Set]]: element.[[Set]] }.
          3. Else,
             1. Let combined be PrivateElement { [[Key]]: element.[[Key]], [[Kind]]: accessor, [[Get]]: element.[[Get]], [[Set]]: pe.[[Set]] }.
          4. Replace pe 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.
27. Set the running execution context's LexicalEnvironment to env.
28. If classBinding is not undefined, then
    1. Perform ! classEnv.InitializeBinding(classBinding, F).
29. Set F.[[PrivateMethods]] to instancePrivateMethods.
30. Set F.[[Fields]] to instanceFields.
31. For each PrivateElement method of staticPrivateMethods, do
    1. Perform ! PrivateMethodOrAccessorAdd(F, method).
32. For each element elementRecord of staticElements, do
    1. If elementRecord is a ClassFieldDefinition Record, then
       1. Let result be Completion(DefineField(F, elementRecord)).
    2. Else,
       1. Assert: elementRecord is a ClassStaticBlockDefinition Record.
       2. Let result be Completion(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.
33. Set the running execution context's PrivateEnvironment to outerPrivateEnvironment.
34. Return F.

# 15.7.15 Runtime Semantics: BindingClassDeclarationEvaluation

The syntax-directed operation BindingClassDeclarationEvaluation takes no arguments and returns either a normal completion containing a function object or an abrupt completion. It is defined piecewise over the following productions:

ClassDeclaration : class BindingIdentifier ClassTail

1. Let className be the StringValue of BindingIdentifier.
2. Let sourceText be the source text matched by ClassDeclaration.
3. Let value be ? ClassDefinitionEvaluation of ClassTail with arguments className, className, and sourceText.
4. Let env be the running execution context's LexicalEnvironment.
5. Perform ? InitializeBoundName(className, value, env).
6. Return value.

ClassDeclaration : class ClassTail

1. Let sourceText be the source text matched by ClassDeclaration.
2. Return ? ClassDefinitionEvaluation of ClassTail with arguments undefined, "default", and sourceText.

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 empty.

Note

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

ClassExpression : class ClassTail

1. Let sourceText be the source text matched by ClassExpression.
2. Return ? ClassDefinitionEvaluation of ClassTail with arguments undefined, "", and sourceText.

ClassExpression : class BindingIdentifier ClassTail

1. Let className be the StringValue of BindingIdentifier.
2. Let sourceText be the source text matched by ClassExpression.
3. Return ? ClassDefinitionEvaluation of ClassTail with arguments className, className, and sourceText.

ClassElementName : PrivateIdentifier

1. Let privateIdentifier be the 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 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:

- In an AsyncFunctionBody.
- In the FormalParameters of an AsyncFunctionDeclaration, AsyncFunctionExpression, AsyncGeneratorDeclaration, or AsyncGeneratorExpression. AwaitExpression in this position is a Syntax error via static semantics.
- In a Module.

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:

- Anywhere outside of an AsyncFunctionBody or FormalParameters of an AsyncFunctionDeclaration, AsyncFunctionExpression, AsyncGeneratorDeclaration, or AsyncGeneratorExpression.
- In the BindingIdentifier of a FunctionExpression, GeneratorExpression, or AsyncGeneratorExpression.

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 }

- It is a Syntax Error if FunctionBodyContainsUseStrict of AsyncFunctionBody is true and IsSimpleParameterList of UniqueFormalParameters is false.
- It is a Syntax Error if HasDirectSuper of AsyncMethod is true.
- It is a Syntax Error if UniqueFormalParameters Contains AwaitExpression is true.
- It is a Syntax Error if any element of the BoundNames of UniqueFormalParameters also occurs in the LexicallyDeclaredNames of AsyncFunctionBody.

AsyncFunctionDeclaration : async function BindingIdentifier ( FormalParameters ) { AsyncFunctionBody } async function ( FormalParameters ) { AsyncFunctionBody } AsyncFunctionExpression : async function BindingIdentifier opt ( FormalParameters ) { AsyncFunctionBody }

- It is a Syntax Error if FunctionBodyContainsUseStrict of AsyncFunctionBody is true and IsSimpleParameterList of FormalParameters is false.
- It is a Syntax Error if FormalParameters Contains AwaitExpression is true.
- If IsStrict(FormalParameters) is true, the Early Error rules for UniqueFormalParameters : FormalParameters are applied.
- If BindingIdentifier is present and IsStrict(BindingIdentifier) is true, it is a Syntax Error if the StringValue of BindingIdentifier is either "eval" or "arguments".
- It is a Syntax Error if any element of the BoundNames of FormalParameters also occurs in the LexicallyDeclaredNames of AsyncFunctionBody.
- It is a Syntax Error if FormalParameters Contains SuperProperty is true.
- It is a Syntax Error if AsyncFunctionBody Contains SuperProperty is true.
- It is a Syntax Error if FormalParameters Contains SuperCall is true.
- It is a Syntax Error if AsyncFunctionBody Contains SuperCall is true.

# 15.8.2 Runtime Semantics: InstantiateAsyncFunctionObject

The syntax-directed operation InstantiateAsyncFunctionObject takes arguments env (an Environment Record) and privateEnv (a PrivateEnvironment Record or null) and returns an ECMAScript function object. It is defined piecewise over the following productions:

AsyncFunctionDeclaration : async function BindingIdentifier ( FormalParameters ) { AsyncFunctionBody }

1. Let name be the 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, env, privateEnv).
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, env, privateEnv).
3. Perform SetFunctionName(F, "default").
4. Return F.

# 15.8.3 Runtime Semantics: InstantiateAsyncFunctionExpression

The syntax-directed operation InstantiateAsyncFunctionExpression takes optional argument name (a property key or a Private Name) and returns an ECMAScript function object. It is defined piecewise over the following productions:

AsyncFunctionExpression : async function ( FormalParameters ) { AsyncFunctionBody }

1. If name is not present, set name to "".
2. Let env be the LexicalEnvironment of the running execution context.
3. Let privateEnv 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, env, privateEnv).
6. Perform SetFunctionName(closure, name).
7. Return closure.

AsyncFunctionExpression : async function BindingIdentifier ( FormalParameters ) { AsyncFunctionBody }

1. Assert: name is not present.
2. Set name to the StringValue of BindingIdentifier.
3. Let outerEnv be the LexicalEnvironment of the running execution context.
4. Let funcEnv be NewDeclarativeEnvironment(outerEnv).
5. Perform ! funcEnv.CreateImmutableBinding(name, false).
6. Let privateEnv 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, privateEnv).
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

The syntax-directed operation EvaluateAsyncFunctionBody takes arguments functionObject (an ECMAScript function object) and argumentsList (a List of ECMAScript language values) and returns a return completion. It is defined piecewise over the following productions:

AsyncFunctionBody : FunctionBody

1. Let promiseCapability be ! NewPromiseCapability(%Promise%).
2. Let completion be Completion(FunctionDeclarationInstantiation(functionObject, argumentsList)).
3. If completion is an abrupt completion, then
   1. Perform ! Call(promiseCapability.[[Reject]], undefined, « completion.[[Value]] »).
4. Else,
   1. Perform AsyncFunctionStart(promiseCapability, FunctionBody).
5. Return ReturnCompletion(promiseCapability.[[Promise]]).

# 15.8.5 Runtime Semantics: Evaluation

AsyncFunctionExpression : async function BindingIdentifier opt ( FormalParameters ) { AsyncFunctionBody }

1. Return InstantiateAsyncFunctionExpression of AsyncFunctionExpression.

AwaitExpression : await UnaryExpression

1. Let exprRef be ? Evaluation of 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

- It is a Syntax Error if any element of the BoundNames of AsyncArrowBindingIdentifier also occurs in the LexicallyDeclaredNames of AsyncConciseBody.

AsyncArrowFunction : CoverCallExpressionAndAsyncArrowHead => AsyncConciseBody

- CoverCallExpressionAndAsyncArrowHead must cover an AsyncArrowHead.
- It is a Syntax Error if CoverCallExpressionAndAsyncArrowHead Contains YieldExpression is true.
- It is a Syntax Error if CoverCallExpressionAndAsyncArrowHead Contains AwaitExpression is true.
- It is a Syntax Error if any element of the BoundNames of CoverCallExpressionAndAsyncArrowHead also occurs in the LexicallyDeclaredNames of AsyncConciseBody.
- It is a Syntax Error if AsyncConciseBodyContainsUseStrict of AsyncConciseBody is true and IsSimpleParameterList of CoverCallExpressionAndAsyncArrowHead is false.

# 15.9.2 Static Semantics: AsyncConciseBodyContainsUseStrict

The syntax-directed operation AsyncConciseBodyContainsUseStrict takes no arguments and returns a Boolean. It is defined piecewise over the following productions:

AsyncConciseBody : ExpressionBody

1. Return false.

AsyncConciseBody : { AsyncFunctionBody }

1. Return FunctionBodyContainsUseStrict of AsyncFunctionBody.

# 15.9.3 Runtime Semantics: EvaluateAsyncConciseBody

The syntax-directed operation EvaluateAsyncConciseBody takes arguments functionObject (an ECMAScript function object) and argumentsList (a List of ECMAScript language values) and returns a return completion. It is defined piecewise over the following productions:

AsyncConciseBody : ExpressionBody

1. Let promiseCapability be ! NewPromiseCapability(%Promise%).
2. Let completion be Completion(FunctionDeclarationInstantiation(functionObject, argumentsList)).
3. If completion is an abrupt completion, then
   1. Perform ! Call(promiseCapability.[[Reject]], undefined, « completion.[[Value]] »).
4. Else,
   1. Perform AsyncFunctionStart(promiseCapability, ExpressionBody).
5. Return ReturnCompletion(promiseCapability.[[Promise]]).

# 15.9.4 Runtime Semantics: InstantiateAsyncArrowFunctionExpression

The syntax-directed operation InstantiateAsyncArrowFunctionExpression takes optional argument name (a property key or a Private Name) and returns an ECMAScript function object. It is defined piecewise over the following productions:

AsyncArrowFunction : async AsyncArrowBindingIdentifier => AsyncConciseBody

1. If name is not present, set name to "".
2. Let env be the LexicalEnvironment of the running execution context.
3. Let privateEnv 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, env, privateEnv).
7. Perform SetFunctionName(closure, name).
8. Return closure.

AsyncArrowFunction : CoverCallExpressionAndAsyncArrowHead => AsyncConciseBody

1. If name is not present, set name to "".
2. Let env be the LexicalEnvironment of the running execution context.
3. Let privateEnv 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, env, privateEnv).
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 CallExpression Parse Node, a MemberExpression Parse Node, or an OptionalChain Parse Node) and returns a Boolean. It performs the following steps when called:

1. If IsStrict(call) is false, return false.
2. If call is not contained within a FunctionBody, a ConciseBody, or an 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

The syntax-directed operation HasCallInTailPosition takes argument call (a CallExpression Parse Node, a MemberExpression Parse Node, or an OptionalChain Parse Node) and returns a Boolean.

Note 1

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.

Note 2

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.

It is defined piecewise over the following productions:

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 ( Expression opt ; Expression opt ; Expression opt ) Statement for ( var VariableDeclarationList ; Expression opt ; Expression opt ) Statement for ( LexicalDeclaration Expression opt ; Expression opt ) Statement ForInOfStatement : for ( LeftHandSideExpression in Expression ) Statement for ( var ForBinding in Expression ) Statement for ( ForDeclaration in Expression ) 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 : { CaseClauses opt DefaultClause CaseClauses opt }

1. Let has be false.
2. If the first CaseClauses is present, set has to HasCallInTailPosition of the first CaseClauses with argument call.
3. If has is true, return true.
4. Set has to HasCallInTailPosition of DefaultClause with argument call.
5. If has is true, return true.
6. If the second CaseClauses is present, set has to 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 : StatementList opt DefaultClause : default : StatementList opt

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 try Block Catch Finally

1. Return HasCallInTailPosition of Finally with argument call.

Catch : catch ( CatchParameter ) Block

1. Return HasCallInTailPosition of Block with argument call.

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 ImportCall 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 and returns unused. 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.
3. Return unused.

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.