15.7 Class Definitions
Syntax
A class definition is always
15.7.1 Static Semantics: Early Errors
-
It is a Syntax Error if
ClassHeritage is not present and the following algorithm returnstrue :- Let constructor be
ConstructorMethod ofClassBody . - If constructor is
empty , returnfalse . - Return
HasDirectSuper of constructor.
- Let constructor be
-
It is a Syntax Error if
PrototypePropertyNameList ofClassElementList contains more than one occurrence of"constructor" . -
It is a Syntax Error if
PrivateBoundIdentifiers ofClassElementList 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.
-
It is a Syntax Error if
PropName ofMethodDefinition is not"constructor" andHasDirectSuper ofMethodDefinition istrue . -
It is a Syntax Error if
PropName ofMethodDefinition is"constructor" andSpecialMethod ofMethodDefinition istrue .
-
It is a Syntax Error if
HasDirectSuper ofMethodDefinition istrue . -
It is a Syntax Error if
PropName ofMethodDefinition is"prototype" .
- It is a Syntax Error if
PropName ofFieldDefinition is"constructor" .
-
It is a Syntax Error if
PropName ofFieldDefinition is either"prototype" or"constructor" .
- It is a Syntax Error if
Initializer is present andContainsArguments ofInitializer istrue . - It is a Syntax Error if
Initializer is present andInitializer Contains SuperCall istrue .
- It is a Syntax Error if
StringValue ofPrivateIdentifier is"#constructor" .
-
It is a Syntax Error if the
LexicallyDeclaredNames ofClassStaticBlockStatementList contains any duplicate entries. -
It is a Syntax Error if any element of the
LexicallyDeclaredNames ofClassStaticBlockStatementList also occurs in theVarDeclaredNames ofClassStaticBlockStatementList . -
It is a Syntax Error if
ContainsDuplicateLabels ofClassStaticBlockStatementList with argument « » istrue . -
It is a Syntax Error if
ContainsUndefinedBreakTarget ofClassStaticBlockStatementList with argument « » istrue . -
It is a Syntax Error if
ContainsUndefinedContinueTarget ofClassStaticBlockStatementList with arguments « » and « » istrue . -
It is a Syntax Error if
ContainsArguments ofClassStaticBlockStatementList istrue . -
It is a Syntax Error if
ClassStaticBlockStatementList Contains SuperCall istrue . -
It is a Syntax Error if
ClassStaticBlockStatementList Contains await
istrue .
15.7.2 Static Semantics: ClassElementKind
The
- If
PropName ofMethodDefinition is"constructor" , returnconstructor-method . - Return
non-constructor-method .
- Return
non-constructor-method .
- Return
non-constructor-method .
- Return
empty .
15.7.3 Static Semantics: ConstructorMethod
The
- If
ClassElementKind ofClassElement isconstructor-method , returnClassElement . - Return
empty .
- Let head be
ConstructorMethod ofClassElementList . - If head is not
empty , return head. - If
ClassElementKind ofClassElement isconstructor-method , returnClassElement . - Return
empty .
Early Error rules ensure that there is only one method definition named
15.7.4 Static Semantics: IsStatic
The
- Return
false .
- Return
true .
- Return
false .
- Return
true .
- Return
true .
- Return
false .
15.7.5 Static Semantics: NonConstructorElements
The
- If
ClassElementKind ofClassElement isnon-constructor-method , then- Return «
ClassElement ».
- Return «
- Return a new empty
List .
- Let list be
NonConstructorElements ofClassElementList . - If
ClassElementKind ofClassElement isnon-constructor-method , then- Append
ClassElement to the end of list.
- Append
- Return list.
15.7.6 Static Semantics: PrototypePropertyNameList
The
- Let propName be
PropName ofClassElement . - If propName is
empty , return a new emptyList . - If
IsStatic ofClassElement istrue , return a new emptyList . - Return « propName ».
- Let list be
PrototypePropertyNameList ofClassElementList . - Let propName be
PropName ofClassElement . - If propName is
empty , return list. - If
IsStatic ofClassElement istrue , return list. - Return the
list-concatenation of list and « propName ».
15.7.7 Static Semantics: AllPrivateIdentifiersValid
The
Every grammar production alternative in this specification which is not listed below implicitly has the following default definition of AllPrivateIdentifiersValid:
- For each child node child of this
Parse Node , do- If child is an instance of a nonterminal, then
- If
AllPrivateIdentifiersValid of child with argument names isfalse , returnfalse .
- If
- If child is an instance of a nonterminal, then
- Return
true .
- If names contains the
StringValue ofPrivateIdentifier , then- Return
AllPrivateIdentifiersValid ofMemberExpression with argument names.
- Return
- Return
false .
- If names contains the
StringValue ofPrivateIdentifier , then- Return
AllPrivateIdentifiersValid ofCallExpression with argument names.
- Return
- Return
false .
- If names contains the
StringValue ofPrivateIdentifier , returntrue . - Return
false .
- If names contains the
StringValue ofPrivateIdentifier , then- Return
AllPrivateIdentifiersValid ofOptionalChain with argument names.
- Return
- Return
false .
- Let newNames be the
list-concatenation of names andPrivateBoundIdentifiers ofClassBody . - Return
AllPrivateIdentifiersValid ofClassElementList with argument newNames.
- If names contains the
StringValue ofPrivateIdentifier , then- Return
AllPrivateIdentifiersValid ofShiftExpression with argument names.
- Return
- Return
false .
15.7.8 Static Semantics: PrivateBoundIdentifiers
The
- Return
PrivateBoundIdentifiers ofClassElementName .
- Return a
List whose sole element is theStringValue ofPrivateIdentifier .
- Return a new empty
List .
- Let names1 be
PrivateBoundIdentifiers ofClassElementList . - Let names2 be
PrivateBoundIdentifiers ofClassElement . - Return the
list-concatenation of names1 and names2.
- Return
PrivateBoundIdentifiers ofClassElementName .
15.7.9 Static Semantics: ContainsArguments
The
Every grammar production alternative in this specification which is not listed below implicitly has the following default definition of ContainsArguments:
- For each child node child of this
Parse Node , do- If child is an instance of a nonterminal, then
- If
ContainsArguments of child istrue , returntrue .
- If
- If child is an instance of a nonterminal, then
- Return
false .
- If the
StringValue ofIdentifier is"arguments" , returntrue . - Return
false .
- Return
false .
- Return
ContainsArguments ofClassElementName .
15.7.10 Runtime Semantics: ClassFieldDefinitionEvaluation
The
- Let name be ?
Evaluation ofClassElementName . - If
Initializer is present, then- Let formalParameterList be an instance of the production
.FormalParameters : [empty] - Let env be the LexicalEnvironment of the
running execution context . - Let privateEnv be the
running execution context 's PrivateEnvironment. - Let sourceText be the empty sequence of Unicode code points.
- Let initializer be
OrdinaryFunctionCreate (%Function.prototype% , sourceText, formalParameterList,Initializer ,non-lexical-this , env, privateEnv). - Perform
MakeMethod (initializer, homeObject). - Set initializer.[[ClassFieldInitializerName]] to name.
- Let formalParameterList be an instance of the production
- Else,
- Let initializer be
empty .
- Let initializer be
- Return the
ClassFieldDefinition Record { [[Name]]: name, [[Initializer]]: initializer }.
15.7.11 Runtime Semantics: ClassStaticBlockDefinitionEvaluation
The
- Let lex be the
running execution context 's LexicalEnvironment. - Let privateEnv be the
running execution context 's PrivateEnvironment. - Let sourceText be the empty sequence of Unicode code points.
- Let formalParameters be an instance of the production
.FormalParameters : [empty] - Let bodyFunction be
OrdinaryFunctionCreate (%Function.prototype% , sourceText, formalParameters,ClassStaticBlockBody ,non-lexical-this , lex, privateEnv). - Perform
MakeMethod (bodyFunction, homeObject). - Return the
ClassStaticBlockDefinition Record { [[BodyFunction]]: bodyFunction }.
15.7.12 Runtime Semantics: EvaluateClassStaticBlockBody
The
Assert : functionObject is a synthetic function created byClassStaticBlockDefinitionEvaluation step5 .- Perform !
FunctionDeclarationInstantiation (functionObject, « »). - Return ?
Evaluation ofClassStaticBlockStatementList .
15.7.13 Runtime Semantics: ClassElementEvaluation
The
- Return ?
ClassFieldDefinitionEvaluation ofFieldDefinition with argument object.
- Return ?
MethodDefinitionEvaluation ofMethodDefinition with arguments object andfalse .
- Return
ClassStaticBlockDefinitionEvaluation ofClassStaticBlock with argument object.
- Return
unused .
15.7.14 Runtime Semantics: ClassDefinitionEvaluation
The
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 this
value. Looking up an instance private method on an object then consists of checking that the class
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:
- Let env be the LexicalEnvironment of the
running execution context . - Let classEnv be
NewDeclarativeEnvironment (env). - If classBinding is not
undefined , then- Perform ! classEnv.CreateImmutableBinding(classBinding,
true ).
- Perform ! classEnv.CreateImmutableBinding(classBinding,
- Let outerPrivateEnvironment be the
running execution context 's PrivateEnvironment. - Let classPrivateEnvironment be
NewPrivateEnvironment (outerPrivateEnvironment). - If
ClassBody is present, then- For each String dn of the
PrivateBoundIdentifiers ofClassBody , do- If classPrivateEnvironment.[[Names]] contains a
Private Name pn such that pn.[[Description]] is dn, thenAssert : This is only possible for getter/setter pairs.
- Else,
- Let name be a new
Private Name whose [[Description]] is dn. - Append name to classPrivateEnvironment.[[Names]].
- Let name be a new
- If classPrivateEnvironment.[[Names]] contains a
- For each String dn of the
- If
ClassHeritage is not present, then- Let protoParent be
%Object.prototype% . - Let constructorParent be
%Function.prototype% .
- Let protoParent be
- Else,
- Set the
running execution context 's LexicalEnvironment to classEnv. - NOTE: The
running execution context 's PrivateEnvironment is outerPrivateEnvironment when evaluatingClassHeritage . - Let superclassRef be
Completion (Evaluation ofClassHeritage ). - Set the
running execution context 's LexicalEnvironment to env. - Let superclass be ?
GetValue (? superclassRef). - If superclass is
null , then- Let protoParent be
null . - Let constructorParent be
%Function.prototype% .
- Let protoParent be
- Else if
IsConstructor (superclass) isfalse , then- Throw a
TypeError exception.
- Throw a
- Else,
- Let protoParent be ?
Get (superclass,"prototype" ). - If protoParent
is not an Object and protoParent is notnull , throw aTypeError exception. - Let constructorParent be superclass.
- Let protoParent be ?
- Set the
- Let proto be
OrdinaryObjectCreate (protoParent). - If
ClassBody is not present, let constructor beempty . - Else, let constructor be
ConstructorMethod ofClassBody . - Set the
running execution context 's LexicalEnvironment to classEnv. - Set the
running execution context 's PrivateEnvironment to classPrivateEnvironment. - If constructor is
empty , then- Let defaultConstructor be a new
Abstract Closure with no parameters that captures nothing and performs the following steps when called:- Let args be the
List of arguments that was passed to this function by [[Call]] or [[Construct]]. - If NewTarget is
undefined , throw aTypeError exception. - Let F be the
active function object . - If F.[[ConstructorKind]] is
derived , then- NOTE: This branch behaves similarly to
constructor(...args) { super(...args); }
. The most notable distinction is that while the aforementionedECMAScript source text observably calls the@@iterator method on%Array.prototype%
, this function does not. - Let func be ! F.[[GetPrototypeOf]]().
- If
IsConstructor (func) isfalse , throw aTypeError exception. - Let result be ?
Construct (func, args, NewTarget).
- NOTE: This branch behaves similarly to
- Else,
- NOTE: This branch behaves similarly to
constructor() {}
. - Let result be ?
OrdinaryCreateFromConstructor (NewTarget,"%Object.prototype%" ).
- NOTE: This branch behaves similarly to
- Perform ?
InitializeInstanceElements (result, F). - Return result.
- Let args be the
- Let F be
CreateBuiltinFunction (defaultConstructor, 0, className, « [[ConstructorKind]], [[SourceText]] »,the current Realm Record , constructorParent).
- Let defaultConstructor be a new
- Else,
- Let constructorInfo be !
DefineMethod of constructor with arguments proto and constructorParent. - Let F be constructorInfo.[[Closure]].
- Perform
MakeClassConstructor (F). - Perform
SetFunctionName (F, className).
- Let constructorInfo be !
- Perform
MakeConstructor (F,false , proto). - If
ClassHeritage is present, set F.[[ConstructorKind]] toderived . - Perform
CreateMethodProperty (proto,"constructor" , F). - If
ClassBody is not present, let elements be a new emptyList . - Else, let elements be
NonConstructorElements ofClassBody . - Let instancePrivateMethods be a new empty
List . - Let staticPrivateMethods be a new empty
List . - Let instanceFields be a new empty
List . - Let staticElements be a new empty
List . - For each
ClassElement e of elements, do- If
IsStatic of e isfalse , then- Let element be
Completion (ClassElementEvaluation of e with argument proto).
- Let element be
- Else,
- Let element be
Completion (ClassElementEvaluation of e with argument F).
- Let element be
- If element is an
abrupt completion , then- Set the
running execution context 's LexicalEnvironment to env. - Set the
running execution context 's PrivateEnvironment to outerPrivateEnvironment. - Return ? element.
- Set the
- Set element to ! element.
- If element is a
PrivateElement , thenAssert : element.[[Kind]] is eithermethod oraccessor .- If
IsStatic of e isfalse , let container be instancePrivateMethods. - Else, let container be staticPrivateMethods.
- If container contains a
PrivateElement pe such that pe.[[Key]] is element.[[Key]], thenAssert : element.[[Kind]] and pe.[[Kind]] are bothaccessor .- If element.[[Get]] is
undefined , then- Let combined be
PrivateElement { [[Key]]: element.[[Key]], [[Kind]]:accessor , [[Get]]: pe.[[Get]], [[Set]]: element.[[Set]] }.
- Let combined be
- Else,
- Let combined be
PrivateElement { [[Key]]: element.[[Key]], [[Kind]]:accessor , [[Get]]: element.[[Get]], [[Set]]: pe.[[Set]] }.
- Let combined be
- Replace pe in container with combined.
- Else,
- Append element to container.
- Else if element is a
ClassFieldDefinition Record , then- If
IsStatic of e isfalse , append element to instanceFields. - Else, append element to staticElements.
- If
- Else if element is a
ClassStaticBlockDefinition Record , then- Append element to staticElements.
- If
- Set the
running execution context 's LexicalEnvironment to env. - If classBinding is not
undefined , then- Perform ! classEnv.InitializeBinding(classBinding, F).
- Set F.[[PrivateMethods]] to instancePrivateMethods.
- Set F.[[Fields]] to instanceFields.
- For each
PrivateElement method of staticPrivateMethods, do- Perform !
PrivateMethodOrAccessorAdd (F, method).
- Perform !
- For each element elementRecord of staticElements, do
- If elementRecord is a
ClassFieldDefinition Record , then- Let result be
Completion (DefineField (F, elementRecord)).
- Let result be
- Else,
Assert : elementRecord is aClassStaticBlockDefinition Record .- Let result be
Completion (Call (elementRecord.[[BodyFunction]], F)).
- If result is an
abrupt completion , then- Set the
running execution context 's PrivateEnvironment to outerPrivateEnvironment. - Return ? result.
- Set the
- If elementRecord is a
- Set the
running execution context 's PrivateEnvironment to outerPrivateEnvironment. - Return F.
15.7.15 Runtime Semantics: BindingClassDeclarationEvaluation
The
- Let className be
StringValue ofBindingIdentifier . - Let value be ?
ClassDefinitionEvaluation ofClassTail with arguments className and className. - Set value.[[SourceText]] to the
source text matched by ClassDeclaration . - Let env be the
running execution context 's LexicalEnvironment. - Perform ?
InitializeBoundName (className, value, env). - Return value.
- Let value be ?
ClassDefinitionEvaluation ofClassTail with argumentsundefined and"default" . - Set value.[[SourceText]] to the
source text matched by ClassDeclaration . - Return value.
15.7.16 Runtime Semantics: Evaluation
- Perform ?
BindingClassDeclarationEvaluation of thisClassDeclaration . - Return
empty .
- Let value be ?
ClassDefinitionEvaluation ofClassTail with argumentsundefined and"" . - Set value.[[SourceText]] to the
source text matched by ClassExpression . - Return value.
- Let className be
StringValue ofBindingIdentifier . - Let value be ?
ClassDefinitionEvaluation ofClassTail with arguments className and className. - Set value.[[SourceText]] to the
source text matched by ClassExpression . - Return value.
- Let privateIdentifier be
StringValue ofPrivateIdentifier . - Let privateEnvRec be the
running execution context 's PrivateEnvironment. - Let names be privateEnvRec.[[Names]].
Assert : Exactly one element of names is aPrivate Name whose [[Description]] is privateIdentifier.- Let privateName be the
Private Name in names whose [[Description]] is privateIdentifier. - Return privateName.
- Return
undefined .