Stage 1 Draft / July 27, 2017

Optional Chaining

1Scope

This is the spec text proposal for introducing Optional Chaining feature (aka Null Propagation, aka Existential Operator) in ECMAScript.

For the syntax, we use the ?. token, with a lookahead at the level of the lexical grammar that allows to discriminate between a?.b (optional chaining) and a?.3:0 (conditional operator, whose meaning cannot be changed due to backward compatibility constraints).

Modified content are marked like this. In order to avoid distraction, we don’t mark mere editorial amendments.

Deprecation notice

A major rewrite is in progress, that will eliminate the need of Nil reference. The observed behaviour will change in edge or rare cases only.

2The Nil Reference

2.1(6.2.4) The Reference Specification Type

Note

The Reference type is used to explain the behaviour of such operators as delete, typeof, the assignment operators, the super keyword and other language features. For example, the left-hand operand of an assignment is expected to produce a reference.

A Reference is a resolved name or property binding. A Reference consists of three components, the base value component, the referenced name component, and the Boolean-valued strict reference flag. The base value component is either undefined, an Object, a Boolean, a String, a Symbol, a Number, or an Environment Record. A base value component of undefined indicates that the Reference could not be resolved to a binding. The referenced name component is a String or Symbol value.

A Super Reference is a Reference that is used to represents a name binding that was expressed using the super keyword. A Super Reference has an additional thisValue component, and its base value component will never be an Environment Record.

A Nil Reference is a special Reference that is used to propagate an undefined value that is produced by the optional chaining special form (?.). A Nil Reference has only one component, the base value component, which is always equal to the symbol Nil.

The following abstract operations are used in this specification to operate on references:

2.1.1GetBase ( V )

  1. Assert: Type(V) is Reference.
  2. Return the base value component of V.

2.1.2GetReferencedName ( V )

  1. Assert: Type(V) is Reference.
  2. Assert: IsNilReference(V) is false.
  3. Return the referenced name component of V.

2.1.3IsStrictReference ( V )

  1. Assert: Type(V) is Reference.
  2. Assert: IsNilReference(V) is false.
  3. Return the strict reference flag of V.

2.1.4HasPrimitiveBase ( V )

  1. Assert: Type(V) is Reference.
  2. If Type(V's base value component) is Boolean, String, Symbol, or Number, return true; otherwise return false.

2.1.5IsPropertyReference ( V )

  1. Assert: Type(V) is Reference.
  2. If either the base value component of V is an Object or HasPrimitiveBase(V) is true, return true; otherwise return false.

2.1.6IsUnresolvableReference ( V )

  1. Assert: Type(V) is Reference.
  2. If the base value component of V is undefined, return true; otherwise return false.

2.1.7IsSuperReference ( V )

  1. Assert: Type(V) is Reference.
  2. If V has a thisValue component, return true; otherwise return false.

2.1.8IsNilReference ( V )

  1. Assert: Type(V) is Reference.
  2. If the base value component of V is the symbol Nil, return true; otherwise, return false.

2.1.9GetValue ( V )

  1. ReturnIfAbrupt(V).
  2. If Type(V) is not Reference, return V.
  3. Let base be GetBase(V).
  4. If IsNilReference(V) is true, return undefined.
  5. If IsUnresolvableReference(V) is true, throw a ReferenceError exception.
  6. If IsPropertyReference(V) is true, then
    1. If HasPrimitiveBase(V) is true, then
      1. Assert: In this case, base will never be undefined or null.
      2. Set base to ! ToObject(base).
    2. Return ? base.[[Get]](GetReferencedName(V), GetThisValue(V)).
  7. Else base must be an Environment Record,
    1. Return ? base.GetBindingValue(GetReferencedName(V), IsStrictReference(V)) (see 8.1.1).
Note

The object that may be created in step 5.a.ii is not accessible outside of the above abstract operation and the ordinary object [[Get]] internal method. An implementation might choose to avoid the actual creation of the object.

2.1.10PutValue ( V, W )

  1. ReturnIfAbrupt(V).
  2. ReturnIfAbrupt(W).
  3. If Type(V) is not Reference, throw a ReferenceError exception.
  4. Let base be GetBase(V).
  5. Assert: IsNilReference(V) is false.
  6. If IsUnresolvableReference(V) is true, then
    1. If IsStrictReference(V) is true, then
      1. Throw a ReferenceError exception.
    2. Let globalObj be GetGlobalObject().
    3. Return ? Set(globalObj, GetReferencedName(V), W, false).
  7. Else if IsPropertyReference(V) is true, then
    1. If HasPrimitiveBase(V) is true, then
      1. Assert: In this case, base will never be undefined or null.
      2. Set base to ! ToObject(base).
    2. Let succeeded be ? base.[[Set]](GetReferencedName(V), W, GetThisValue(V)).
    3. If succeeded is false and IsStrictReference(V) is true, throw a TypeError exception.
    4. Return.
  8. Else base must be an Environment Record,
    1. Return ? base.SetMutableBinding(GetReferencedName(V), W, IsStrictReference(V)) (see 8.1.1).
Note

The object that may be created in step 6.a.ii is not accessible outside of the above algorithm and the ordinary object [[Set]] internal method. An implementation might choose to avoid the actual creation of that object.

2.1.11GetThisValue ( V )

  1. Assert: IsPropertyReference(V) is true.
  2. If IsSuperReference(V) is true, then
    1. Return the value of the thisValue component of the reference V.
  3. Return GetBase(V).

2.1.12InitializeReferencedBinding ( V, W )

  1. ReturnIfAbrupt(V).
  2. ReturnIfAbrupt(W).
  3. Assert: Type(V) is Reference.
  4. Assert: IsNilReference(V) is false.
  5. Assert: IsUnresolvableReference(V) is false.
  6. Let base be GetBase(V).
  7. Assert: base is an Environment Record.
  8. Return base.InitializeBinding(GetReferencedName(V), W).

2.2(12.5.3) The delete Operator

2.2.1Static Semantics: Early Errors

UnaryExpression:deleteUnaryExpression Note

The last rule means that expressions such as delete (((foo))) produce early errors because of recursive application of the first rule.

2.2.2Runtime Semantics: Evaluation

UnaryExpression:deleteUnaryExpression
  1. Let ref be the result of evaluating UnaryExpression.
  2. ReturnIfAbrupt(ref).
  3. If Type(ref) is not Reference, return true.
  4. If IsNilReference(ref) is true, return true.
  5. If IsUnresolvableReference(ref) is true, then
    1. Assert: IsStrictReference(ref) is false.
    2. Return true.
  6. If IsPropertyReference(ref) is true, then
    1. If IsSuperReference(ref) is true, throw a ReferenceError exception.
    2. Let baseObj be ! ToObject(GetBase(ref)).
    3. Let deleteStatus be ? baseObj.[[Delete]](GetReferencedName(ref)).
    4. If deleteStatus is false and IsStrictReference(ref) is true, throw a TypeError exception.
    5. Return deleteStatus.
  7. Else ref is a Reference to an Environment Record binding,
    1. Let bindings be GetBase(ref).
    2. Return ? bindings.DeleteBinding(GetReferencedName(ref)).
Note

When a delete operator occurs within strict mode code, a SyntaxError exception is thrown if its UnaryExpression is a direct reference to a variable, function argument, or function name. In addition, if a delete operator occurs within strict mode code and the property to be deleted has the attribute { [[Configurable]]: false }, a TypeError exception is thrown.

3(11.7) Lexical Grammar: Punctuators

Syntax

OptionalChainingOperator::?.[lookahead ∉ DecimalDigit] OtherPunctuator::one of{()[]....;,<><=>===!====!==+-*%**++--<<>>>>>&|^!~&&||?:=+=-=*=%=**=<<=>>=>>>=&=|=^==> Punctuator::OptionalChainingOperator OtherPunctuator DivPunctuator::/ /= RightBracePunctuator::}

4(12.2) Primary Expression

Syntax

PrimaryExpression[Yield, Await]:this IdentifierReference[?Yield, ?Await] Literal ArrayLiteral[?Yield, ?Await] ObjectLiteral[?Yield, ?Await] FunctionExpression ClassExpression[?Yield, ?Await] GeneratorExpression AsyncFunctionExpression RegularExpressionLiteral TemplateLiteral[?Yield, ?Await] CoverParenthesizedExpressionAndArrowParameterList[?Yield, ?Await] CoverParenthesizedExpressionAndArrowParameterList[Yield, Await]:(Expression[+In, ?Yield, ?Await]) (Expression[+In, ?Yield, ?Await],) () (...BindingIdentifier[?Yield, ?Await]) (...BindingPattern[?Yield, ?Await]) (Expression[+In, ?Yield, ?Await],...BindingIdentifier[?Yield, ?Await]) (Expression[+In, ?Yield, ?Await],...BindingPattern[?Yield, ?Await])

Supplemental Syntax

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

ParenthesizedExpression[Yield, Await]:(Expression[+In, ?Yield, ?Await])

4.1(12.2.1) Semantics

4.1.1Static Semantics: CoveredParenthesizedExpression

CoverParenthesizedExpressionAndArrowParameterList[Yield, Await]:(Expression[+In, ?Yield, ?Await])
  1. Return the result of parsing the lexical token stream matched by CoverParenthesizedExpressionAndArrowParameterList using ParenthesizedExpression as the goal symbol with its [Yield] and [Await] parameters set to the values used when parsing this CoverParenthesizedExpressionAndArrowParameterList.

4.1.2Static Semantics: HasName

PrimaryExpression:CoverParenthesizedExpressionAndArrowParameterList
  1. Let expr be CoveredParenthesizedExpression of CoverParenthesizedExpressionAndArrowParameterList.
  2. If IsFunctionDefinition of expr is false, return false.
  3. Return HasName of expr.

4.1.3Static Semantics: IsFunctionDefinition

PrimaryExpression:this IdentifierReference Literal ArrayLiteral ObjectLiteral RegularExpressionLiteral TemplateLiteral
  1. Return false.
PrimaryExpression:CoverParenthesizedExpressionAndArrowParameterList
  1. Let expr be CoveredParenthesizedExpression of CoverParenthesizedExpressionAndArrowParameterList.
  2. Return IsFunctionDefinition of expr.

4.1.4Static Semantics: IsIdentifierRef

PrimaryExpression:IdentifierReference
  1. Return true.
PrimaryExpression:this Literal ArrayLiteral ObjectLiteral FunctionExpression ClassExpression GeneratorExpression AsyncFunctionExpression RegularExpressionLiteral TemplateLiteral CoverParenthesizedExpressionAndArrowParameterList
  1. Return false.

4.1.5Static Semantics: IsValidSimpleAssignmentTarget

PrimaryExpression:this Literal ArrayLiteral ObjectLiteral FunctionExpression ClassExpression GeneratorExpression AsyncFunctionExpression RegularExpressionLiteral TemplateLiteral
  1. Return false.
PrimaryExpression:CoverParenthesizedExpressionAndArrowParameterList
  1. Let expr be CoveredParenthesizedExpression of CoverParenthesizedExpressionAndArrowParameterList.
  2. Return IsValidSimpleAssignmentTarget of expr.

4.1.6Static Semantics: MayProduceNil

PrimaryExpression:this Literal ArrayLiteral ObjectLiteral FunctionExpression ClassExpression GeneratorExpression AsyncFunctionExpression RegularExpressionLiteral TemplateLiteral
  1. Return false.
PrimaryExpression:CoverParenthesizedExpressionAndArrowParameterList
  1. Let expr be CoveredParenthesizedExpression of CoverParenthesizedExpressionAndArrowParameterList.
  2. Return MayProduceNil of expr.

4.2(12.2.2) The this Keyword

(not modified)

4.3(12.2.3) Identifier Reference

(not modified)

4.4(12.2.4) Literals

(not modified)

4.5(12.2.5) Array Initializer

(not modified)

4.6(12.2.6) Object Initializer

(not modified)

4.7(12.2.7) Function Defining Expressions

(not modified)

4.8(12.2.8) Regular Expression Literals

(not modified)

4.9(12.2.9) Template Literals

(not modified)

4.10(12.2.10) The Grouping Operator

4.10.1Static Semantics: Early Errors

PrimaryExpression:CoverParenthesizedExpressionAndArrowParameterList

4.10.2Static Semantics: IsFunctionDefinition

ParenthesizedExpression:(Expression)
  1. Return IsFunctionDefinition of Expression.

4.10.3Static Semantics: IsValidSimpleAssignmentTarget

ParenthesizedExpression:(Expression)
  1. Return IsValidSimpleAssignmentTarget of Expression.

4.10.4Static Semantics: MayProduceNil

ParenthesizedExpression:(Expression)
  1. Return MayProduceNil of Expression.

4.10.5Runtime Semantics: Evaluation

PrimaryExpression:CoverParenthesizedExpressionAndArrowParameterList
  1. Let expr be CoveredParenthesizedExpression of CoverParenthesizedExpressionAndArrowParameterList.
  2. Return the result of evaluating expr.
ParenthesizedExpression:(Expression)
  1. Return the result of evaluating Expression. This may be of type Reference.
Note

This algorithm does not apply GetValue to the result of evaluating Expression. The principal motivation for this is so that operators such as delete and typeof may be applied to parenthesized expressions.

5(12.3) Left-Hand-Side Expressions

Syntax

MemberExpression[Yield, Await]:PrimaryExpression[?Yield, ?Await] MemberExpression[?Yield, ?Await][Expression[+In, ?Yield, ?Await]] MemberExpression[?Yield, ?Await]OptionalChainingOperator[Expression[+In, ?Yield, ?Await]] MemberExpression[?Yield, ?Await].IdentifierName MemberExpression[?Yield, ?Await]OptionalChainingOperatorIdentifierName MemberExpression[?Yield, ?Await]TemplateLiteral[?Yield, ?Await] SuperProperty[?Yield, ?Await] MetaProperty newMemberExpression[?Yield, ?Await]Arguments[?Yield, ?Await] newMemberExpression[?Yield, ?Await]OptionalChainingOperatorArguments[?Yield, ?Await] SuperProperty[Yield, Await]:super[Expression[+In, ?Yield, ?Await]] super.IdentifierName MetaProperty:NewTarget NewTarget:new.target NewExpression[Yield, Await]:MemberExpression[?Yield, ?Await] newNewExpression[?Yield, ?Await] CallExpression[Yield, Await]:CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await] MemberExpression[?Yield, ?Await]OptionalChainingOperatorArguments[?Yield] SuperCall[?Yield, ?Await] CallExpression[?Yield, ?Await]Arguments[?Yield, ?Await] CallExpression[?Yield, ?Await]OptionalChainingOperatorArguments[?Yield, ?Await] CallExpression[?Yield, ?Await][Expression[+In, ?Yield, ?Await]] CallExpression[?Yield, ?Await]OptionalChainingOperator[Expression[+In, ?Yield, ?Await]] CallExpression[?Yield, ?Await].IdentifierName CallExpression[?Yield, ?Await]OptionalChainingOperatorIdentifierName CallExpression[?Yield, ?Await]TemplateLiteral[?Yield, ?Await] SuperCall[Yield, Await]:superArguments[?Yield, ?Await] Arguments[Yield, Await]:() (ArgumentList[?Yield, ?Await]) (ArgumentList[?Yield, ?Await],) ArgumentList[Yield, Await]:AssignmentExpression[+In, ?Yield, ?Await] ...AssignmentExpression[+In, ?Yield, ?Await] ArgumentList[?Yield, ?Await],AssignmentExpression[+In, ?Yield, ?Await] ArgumentList[?Yield, ?Await],...AssignmentExpression[+In, ?Yield, ?Await] LeftHandSideExpression[Yield, Await]:NewExpression[?Yield, ?Await] CallExpression[?Yield, ?Await]

Supplemental Syntax

When processing an instance of the production CallExpression:CoverCallExpressionAndAsyncArrowHead the interpretation of CoverCallExpressionAndAsyncArrowHead is refined using the following grammar:

CallMemberExpression[Yield, Await]:MemberExpression[?Yield, ?Await]Arguments[?Yield, ?Await]

5.1(12.3.1) Static Semantics

5.1.1Static Semantics: CoveredCallExpression

CallExpression:CoverCallExpressionAndAsyncArrowHead
  1. Return the result of parsing the lexical token stream matched by CoverCallExpressionAndAsyncArrowHead using CallMemberExpression as the goal symbol with its [Yield] and [Await] parameters set to the values used when parsing CoverCallExpressionAndAsyncArrowHead.

5.1.2Static Semantics: Contains

With parameter symbol.

MemberExpression:MemberExpression.IdentifierName MemberExpressionOptionalChainingOperatorIdentifierName
  1. If MemberExpression Contains symbol is true, return true.
  2. If symbol is a ReservedWord, return false.
  3. If symbol is an Identifier and StringValue of symbol is the same value as the StringValue of IdentifierName, return true.
  4. Return false.
SuperProperty:super.IdentifierName
  1. If symbol is the ReservedWord super, return true.
  2. If symbol is a ReservedWord, return false.
  3. If symbol is an Identifier and StringValue of symbol is the same value as the StringValue of IdentifierName, return true.
  4. Return false.
CallExpression:CallExpression.IdentifierName CallExpressionOptionalChainingOperatorIdentifierName
  1. If CallExpression Contains symbol is true, return true.
  2. If symbol is a ReservedWord, return false.
  3. If symbol is an Identifier and StringValue of symbol is the same value as the StringValue of IdentifierName, return true.
  4. Return false.

5.1.3Static Semantics: IsFunctionDefinition

MemberExpression:MemberExpression[Expression] MemberExpressionOptionalChainingOperator[Expression] MemberExpression.IdentifierName MemberExpressionOptionalChainingOperatorIdentifierName MemberExpressionTemplateLiteral SuperProperty MetaProperty newMemberExpressionArguments newMemberExpressionOptionalChainingOperatorArguments NewExpression:newNewExpression LeftHandSideExpression:CallExpression
  1. Return false.

5.1.4Static Semantics: IsDestructuring

MemberExpression:PrimaryExpression
  1. If PrimaryExpression is either an ObjectLiteral or an ArrayLiteral, return true.
  2. Return false.
MemberExpression:MemberExpression[Expression] MemberExpressionOptionalChainingOperator[Expression] MemberExpression.IdentifierName MemberExpressionOptionalChainingOperatorIdentifierName MemberExpressionTemplateLiteral SuperProperty MetaProperty newMemberExpressionArguments newMemberExpressionOptionalChainingOperatorArguments NewExpression:newNewExpression LeftHandSideExpression:CallExpression
  1. Return false.

5.1.5Static Semantics: IsIdentifierRef

MemberExpression:MemberExpression[Expression] MemberExpressionOptionalChainingOperator[Expression] MemberExpression.IdentifierName MemberExpressionOptionalChainingOperatorIdentifierName MemberExpressionTemplateLiteral SuperProperty MetaProperty newMemberExpressionArguments newMemberExpressionOptionalChainingOperatorArguments NewExpression:newNewExpression LeftHandSideExpression:CallExpression
  1. Return false.

5.1.6Static Semantics: IsValidSimpleAssignmentTarget

CallExpression:CallExpression[Expression] CallExpression.IdentifierName
  1. If MayProduceNil of CallExpression is true, return false.
  2. Return true.
MemberExpression:MemberExpression[Expression] MemberExpression.IdentifierName
  1. If MayProduceNil of MemberExpression is true, return false.
  2. Return true.
MemberExpression:SuperProperty
  1. Return true.
CallExpression:CoverCallExpressionAndAsyncArrowHead MemberExpressionOptionalChainingOperatorArguments SuperCall CallExpressionArguments CallExpressionOptionalChainingOperatorArguments CallExpressionOptionalChainingOperator[Expression] MemberExpressionOptionalChainingOperatorIdentifierName CallExpressionTemplateLiteral NewExpression:newNewExpression MemberExpression:MemberExpressionTemplateLiteral newMemberExpressionArguments newMemberExpressionOptionalChainingOperatorArguments NewTarget:new.target
  1. Return false.

5.1.7Static Semantics: MayProduceNil

MemberExpression:MemberExpressionOptionalChainingOperator[Expression] MemberExpressionOptionalChainingOperatorIdentifierName newMemberExpressionOptionalChainingOperatorArguments CallExpression:MemberExpressionOptionalChainingOperatorArguments CallExpressionOptionalChainingOperatorArguments CallExpressionOptionalChainingOperator[Expression] CallExpressionOptionalChainingOperatorIdentifierName
  1. Return true.
MemberExpression:SuperProperty MetaProperty CallExpression:SuperCall
  1. Return false.
MemberExpression:MemberExpression[Expression] MemberExpression.IdentifierName MemberExpressionTemplateLiteral newMemberExpressionArguments CallMemberExpression:MemberExpressionArguments
  1. Return MayProduceNil of MemberExpression.
CallExpression:CallExpressionArguments CallExpression[Expression] CallExpression.IdentifierName CallExpressionTemplateLiteral
  1. Return MayProduceNil of CallExpression.
NewExpression:newNewExpression
  1. Return MayProduceNil of NewExpression.

5.2(12.3.2) Property Accessors

Note

Properties are accessed by name, using either the dot notation:

or the bracket notation:

The dot notation is explained by the following syntactic conversion:

is identical in its behaviour to

MemberExpression [ <identifier-name-string> ]

and similarly

is identical in its behaviour to

CallExpression [ <identifier-name-string> ]

where <identifier-name-string> is the result of evaluating StringValue of IdentifierName.

5.2.1Runtime Semantics: Evaluation

MemberExpression:MemberExpression[Expression]
  1. Let baseReference be the result of evaluating MemberExpression.
  2. ReturnIfAbrupt(baseReference).
  3. If baseReference is a Reference and IsNilReference(baseReference) is true, then
    1. Return baseReference.
  4. Let baseValue be ? GetValue(baseReference).
  5. Let propertyNameReference be the result of evaluating Expression.
  6. Let propertyNameValue be ? GetValue(propertyNameReference).
  7. Let bv be ? RequireObjectCoercible(baseValue).
  8. Let propertyKey be ? ToPropertyKey(propertyNameValue).
  9. If the code matched by this MemberExpression is strict mode code, let strict be true, else let strict be false.
  10. Return a value of type Reference whose base value component is bv, whose referenced name component is propertyKey, and whose strict reference flag is strict.
MemberExpression:MemberExpressionOptionalChainingOperator[Expression]
  1. Let baseReference be the result of evaluating MemberExpression.
  2. Let baseValue be ? GetValue(baseReference).
  3. If baseValue is undefined or null, then
    1. Return a value of type Reference whose base value is Nil.
  4. Let propertyNameReference be the result of evaluating Expression.
  5. Let propertyNameValue be ? GetValue(propertyNameReference).
  6. Let bv be ? RequireObjectCoercible(baseValue).
  7. Let propertyKey be ? ToPropertyKey(propertyNameValue).
  8. If the code matched by this MemberExpression is strict mode code, let strict be true, else let strict be false.
  9. Return a value of type Reference whose base value component is bv, whose referenced name component is propertyKey, and whose strict reference flag is strict.
MemberExpression:MemberExpression.IdentifierName
  1. Let baseReference be the result of evaluating MemberExpression.
  2. ReturnIfAbrupt(baseReference).
  3. If baseReference is a Reference and IsNilReference(baseReference) is true, then
    1. Return baseReference.
  4. Let baseValue be ? GetValue(baseReference).
  5. Let bv be ? RequireObjectCoercible(baseValue).
  6. Let propertyNameString be StringValue of IdentifierName.
  7. If the code matched by this MemberExpression is strict mode code, let strict be true, else let strict be false.
  8. Return a value of type Reference whose base value component is bv, whose referenced name component is propertyNameString, and whose strict reference flag is strict.
MemberExpression:MemberExpressionOptionalChainingOperatorIdentifierName
  1. Let baseReference be the result of evaluating MemberExpression.
  2. Let baseValue be ? GetValue(baseReference).
  3. If baseValue is undefined or null, then
    1. Return a value of type Reference whose base value is Nil.
  4. Let bv be ? RequireObjectCoercible(baseValue).
  5. Let propertyNameString be StringValue of IdentifierName.
  6. If the code matched by this MemberExpression is strict mode code, let strict be true, else let strict be false.
  7. Return a value of type Reference whose base value component is bv, whose referenced name component is propertyNameString, and whose strict reference flag is strict.
CallExpression:CallExpression[Expression]

Is evaluated in exactly the same manner as MemberExpression:MemberExpression[Expression] except that the contained CallExpression is evaluated in step 1.

CallExpression:CallExpressionOptionalChainingOperator[Expression]

Is evaluated in exactly the same manner as MemberExpression:MemberExpressionOptionalChainingOperator[Expression] except that the contained CallExpression is evaluated in step 1.

CallExpression:CallExpression.IdentifierName

Is evaluated in exactly the same manner as MemberExpression:MemberExpression.IdentifierName except that the contained CallExpression is evaluated in step 1.

CallExpression:CallExpressionOptionalChainingOperatorIdentifierName

Is evaluated in exactly the same manner as MemberExpression:MemberExpressionOptionalChainingOperatorIdentifierName except that the contained CallExpression is evaluated in step 1.

5.3(12.3.3) The new Operator

5.3.1Runtime Semantics: Evaluation

NewExpression:newNewExpression
  1. Return ? EvaluateNew(NewExpression, empty, false).
MemberExpression:newMemberExpressionArguments
  1. Return ? EvaluateNew(MemberExpression, Arguments, false).
MemberExpression:newMemberExpressionOptionalChainingOperatorArguments
  1. Return ? EvaluateNew(MemberExpression, Arguments, true).

5.3.1.1Runtime Semantics: EvaluateNew ( constructExpr, arguments , optionalEvaluation)

The abstract operation EvaluateNew with arguments constructExpr, arguments, and optionalEvaluation performs the following steps:

  1. Assert: constructExpr is either a NewExpression or a MemberExpression.
  2. Assert: arguments is either empty or an Arguments.
  3. Let ref be the result of evaluating constructExpr.
  4. ReturnIfAbrupt(ref).
  5. If ref is a Reference and IsNilReference(ref) is true, then
    1. Return ref.
  6. Let constructor be ? GetValue(ref).
  7. If optionalEvaluation is true and constructor is undefined or null, then
    1. Return a value of type Reference whose base value is Nil.
  8. If arguments is empty, let argList be a new empty List.
  9. Else,
    1. Let argList be ArgumentListEvaluation of arguments.
    2. ReturnIfAbrupt(argList).
  10. If IsConstructor(constructor) is false, throw a TypeError exception.
  11. Return ? Construct(constructor, argList).

5.4(12.3.4) Function Calls

5.4.1Runtime Semantics: Evaluation

CallExpression:CoverCallExpressionAndAsyncArrowHead
  1. Let expr be CoveredCallExpression of CoverCallExpressionAndAsyncArrowHead.
  2. Let memberExpr be the MemberExpression of expr.
  3. Let arguments be the Arguments of expr.
  4. Let ref be the result of evaluating memberExpr.
  5. Let func be ? GetValue(ref).
  6. If Type(ref) is Reference, IsNilReference(ref) is false, IsPropertyReference(ref) is false, and GetReferencedName(ref) is "eval", then
    1. If SameValue(func, %eval%) is true, then
      1. Let argList be ? ArgumentListEvaluation(arguments).
      2. If argList has no elements, return undefined.
      3. Let evalText be the first element of argList.
      4. If the source code matching this CallExpression is strict mode code, let strictCaller be true. Otherwise let strictCaller be false.
      5. Let evalRealm be the current Realm Record.
      6. Perform ? HostEnsureCanCompileStrings(evalRealm, evalRealm).
      7. Return ? PerformEval(evalText, evalRealm, strictCaller, true).
  7. If Type(ref) is Reference, then
    1. If IsNilReference(ref) is true, then
      1. Return ref.
    2. If IsPropertyReference(ref) is true, then
      1. Let thisValue be GetThisValue(ref).
    3. Else the base of ref is an Environment Record,
      1. Let refEnv be GetBase(ref).
      2. Let thisValue be refEnv.WithBaseObject().
  8. Else Type(ref) is not Reference,
    1. Let thisValue be undefined.
  9. Let thisCall be this CallExpression.
  10. Let tailCall be IsInTailPosition(thisCall).
  11. Return ? EvaluateDirectCall(func, thisValue, arguments, tailCall, false).

A CallExpression evaluation that executes step 6.a.vii is a direct eval.

CallExpression:MemberExpressionOptionalChainingArguments

Is evaluated in the same manner as CallExpression:CoverCallExpressionAndAsyncArrowHead , except the three first steps, which are replaced by:

  1. Let memberExpr be the MemberExpression of CallExpression.
  2. Let arguments be the Arguments of CallExpression.

and the last step, which is replaced by:

  1. Return ? EvaluateDirectCall(func, thisValue, Arguments, tailCall, true).
CallExpression:CallExpressionArguments
  1. Let ref be the result of evaluating CallExpression.
  2. Let thisCall be this CallExpression.
  3. Let tailCall be IsInTailPosition(thisCall).
  4. Return ? EvaluateCall(ref, Arguments, tailCall, false).
CallExpression:CallExpressionOptionalChainingOperatorArguments
  1. Let ref be the result of evaluating CallExpression.
  2. Let thisCall be this CallExpression.
  3. Let tailCall be IsInTailPosition(thisCall).
  4. Return ? EvaluateCall(ref, Arguments, tailCall, true).

5.4.2Runtime Semantics: EvaluateCall( ref, arguments, tailPosition, optionalEvaluation )

The abstract operation EvaluateCall takes as arguments a value ref, a Parse Node arguments, a Boolean argument tailPosition, and a Boolean argument optionalEvaluation. It performs the following steps:

  1. Let func be ? GetValue(ref).
  2. If Type(ref) is Reference, then
    1. If IsNilReference(ref), then
      1. Return ref.
    2. If IsPropertyReference(ref) is true, then
      1. Let thisValue be GetThisValue(ref).
    3. Else the base of ref is an Environment Record,
      1. Let refEnv be GetBase(ref).
      2. Let thisValue be refEnv.WithBaseObject().
  3. Else Type(ref) is not Reference,
    1. Let thisValue be undefined.
  4. Return ? EvaluateDirectCall(func, thisValue, arguments, tailPosition, optionalEvaluation).

5.4.3Runtime Semantics: EvaluateDirectCall( func, thisValue, arguments, tailPosition, optionalEvaluation )

The abstract operation EvaluateDirectCall takes as arguments a value func, a value thisValue, a Parse Node arguments, a Boolean argument tailPosition, and a Boolean argument optionalEvaluation. It performs the following steps:

  1. If optionalEvaluation is true and func is undefined or null, then
    1. Return a value of type Reference whose base value is Nil.
  2. Let argList be ? ArgumentListEvaluation(arguments).
  3. If Type(func) is not Object, throw a TypeError exception.
  4. If IsCallable(func) is false, throw a TypeError exception.
  5. If tailPosition is true, perform PrepareForTailCall().
  6. Let result be Call(func, thisValue, argList).
  7. Assert: If tailPosition is true, the above call will not return here, but instead evaluation will continue as if the following return has already occurred.
  8. Assert: If result is not an abrupt completion, then Type(result) is an ECMAScript language type.
  9. Return result.

5.5(12.3.5) The super Keyword

(not modified)

5.6(12.3.6) Argument Lists

(not modified)

5.7(12.3.7) Tagged Templates

Note

A tagged template is a function call where the arguments of the call are derived from a TemplateLiteral (4.9). The actual arguments include a template object (12.2.9.3) and the values produced by evaluating the expressions embedded within the TemplateLiteral.

5.7.1Runtime Semantics: Evaluation

MemberExpression:MemberExpressionTemplateLiteral
  1. Let tagRef be the result of evaluating MemberExpression.
  2. Let thisCall be this MemberExpression.
  3. Let tailCall be IsInTailPosition(thisCall).
  4. Return ? EvaluateCall(tagRef, TemplateLiteral, tailCall, false).
CallExpression:CallExpressionTemplateLiteral
  1. Let tagRef be the result of evaluating CallExpression.
  2. Let thisCall be this CallExpression.
  3. Let tailCall be IsInTailPosition(thisCall).
  4. Return ? EvaluateCall(tagRef, TemplateLiteral, tailCall, false).

5.8(12.3.8) Meta Properties

(not modified)