ECMA-262 (12th Edition) ECMAScript 2021 Language Specification - page 43

 

  Главная      Manuals     ECMA-262 (12th Edition) ECMAScript 2021 Language Specification

 

Search            copyright infringement  

 

 

 

 

 

 

 

 

 

 

 

Content      ..     41      42      43      44     ..

 

 

 

ECMA-262 (12th Edition) ECMAScript 2021 Language Specification - page 43

 

 

2.  Let 

tagFunc

 be ? 

GetValue

(

tagRef

).

3.  Let 

thisCall

 be this 

CallExpression

.

4.  Let 

tailCall

 be 

IsInTailPosition

(

thisCall

).

5.  Return ? 

EvaluateCall

(

tagFunc

tagRef

TemplateLiteral

tailCall

).

NewTarget

 

:

 

new

 

.

 

target

1.  Return 

GetNewTarget

().

ImportMeta

 

:

 

import

 

.

 

meta

1.  Let 

module

 be ! 

GetActiveScriptOrModule

().

2. 

Assert

module

 is a 

Source Text Module Record

.

3.  Let 

importMeta

 be 

module

.[[ImportMeta]].

4.  If 

importMeta

 is 

empty

, then

a.  Set 

importMeta

 to ! 

OrdinaryObjectCreate

(

null

).

b.  Let 

importMetaValues

 be ! 

HostGetImportMetaProperties

(

module

).

c.  For each 

Record

 { [[Key]], [[Value]] } 

p

 of 

importMetaValues

, do

i.  Perform ! 

CreateDataPropertyOrThrow

(

importMeta

p

.[[Key]], 

p

.[[Value]]).

d.  Perform ! 

HostFinalizeImportMeta

(

importMeta

module

).

e.  Set 

module

.[[ImportMeta]] to 

importMeta

.

f.  Return 

importMeta

.

5.  Else,

a. 

Assert

Type

(

importMeta

) is Object.

b.  Return 

importMeta

.

The 

host-defined

 abstract operation HostGetImportMetaProperties takes argument 

moduleRecord

 (a 

Module Record

). It

allows hosts to provide property keys and values for the object returned from 

import.meta

import.meta

.

The implementation of HostGetImportMetaProperties must conform to the following requirements:

It must return a 

List

, whose values are all Records with two fields, [[Key]] and [[Value]].

Each such 

Record

's [[Key]] field must be a property key, i.e., 

IsPropertyKey

 must return 

true

 when applied to

it.
Each such 

Record

's [[Value]] field must be an ECMAScript value.

It must always complete normally (i.e., not return an 

abrupt completion

).

The default implementation of HostGetImportMetaProperties is to return a new empty 

List

.

The 

host-defined

 abstract operation HostFinalizeImportMeta takes arguments 

importMeta

 (an Object) and

moduleRecord

 (a 

Module Record

). It allows hosts to perform any extraordinary operations to prepare the object

returned from 

import.meta

import.meta

.

13.3.12  Meta Properties

13.3.12.1  Runtime Semantics: Evaluation

13.3.12.1.1  HostGetImportMetaProperties ( 

moduleRecord

 )

13.3.12.1.2  HostFinalizeImportMeta ( 

importMeta

moduleRecord

 )

330

Most hosts will be able to simply define 

HostGetImportMetaProperties

, and leave HostFinalizeImportMeta with its

default behaviour. However, HostFinalizeImportMeta provides an "escape hatch" for hosts which need to directly
manipulate the object before it is exposed to ECMAScript code.

The implementation of HostFinalizeImportMeta must conform to the following requirements:

It must always complete normally (i.e., not return an 

abrupt completion

).

The default implementation of HostFinalizeImportMeta is to return 

NormalCompletion

(

empty

).

UpdateExpression

[Yield, Await]

 

:

LeftHandSideExpression

[?Yield, ?Await]

LeftHandSideExpression

[?Yield, ?Await]

 [no 

LineTerminator

 here]  

++

LeftHandSideExpression

[?Yield, ?Await]

 [no 

LineTerminator

 here]  

--

++

 

UnaryExpression

[?Yield, ?Await]

--

 

UnaryExpression

[?Yield, ?Await]

UpdateExpression

 

:

LeftHandSideExpression

 

++

LeftHandSideExpression

 

--

It is an early Syntax Error if 

AssignmentTargetType

 of 

LeftHandSideExpression

 is not 

simple

.

UpdateExpression

 

:

++

 

UnaryExpression

--

 

UnaryExpression

It is an early Syntax Error if 

AssignmentTargetType

 of 

UnaryExpression

 is not 

simple

.

UpdateExpression

 

:

 

LeftHandSideExpression

 

++

1.  Let 

lhs

 be the result of evaluating 

LeftHandSideExpression

.

2.  Let 

oldValue

 be ? 

ToNumeric

(? 

GetValue

(

lhs

)).

3.  Let 

newValue

 be ! 

Type

(

oldValue

)::add(

oldValue

Type

(

oldValue

)::unit).

4.  Perform ? 

PutValue

(

lhs

newValue

).

5.  Return 

oldValue

.

13.4  Update Expressions

Syntax

13.4.1  Static Semantics: Early Errors

13.4.2  Postfix Increment Operator

13.4.2.1  Runtime Semantics: Evaluation

13.4.3  Postfix Decrement Operator

331

UpdateExpression

 

:

 

LeftHandSideExpression

 

--

1.  Let 

lhs

 be the result of evaluating 

LeftHandSideExpression

.

2.  Let 

oldValue

 be ? 

ToNumeric

(? 

GetValue

(

lhs

)).

3.  Let 

newValue

 be ! 

Type

(

oldValue

)::subtract(

oldValue

Type

(

oldValue

)::unit).

4.  Perform ? 

PutValue

(

lhs

newValue

).

5.  Return 

oldValue

.

UpdateExpression

 

:

 

++

 

UnaryExpression

1.  Let 

expr

 be the result of evaluating 

UnaryExpression

.

2.  Let 

oldValue

 be ? 

ToNumeric

(? 

GetValue

(

expr

)).

3.  Let 

newValue

 be ! 

Type

(

oldValue

)::add(

oldValue

Type

(

oldValue

)::unit).

4.  Perform ? 

PutValue

(

expr

newValue

).

5.  Return 

newValue

.

UpdateExpression

 

:

 

--

 

UnaryExpression

1.  Let 

expr

 be the result of evaluating 

UnaryExpression

.

2.  Let 

oldValue

 be ? 

ToNumeric

(? 

GetValue

(

expr

)).

3.  Let 

newValue

 be ! 

Type

(

oldValue

)::subtract(

oldValue

Type

(

oldValue

)::unit).

4.  Perform ? 

PutValue

(

expr

newValue

).

5.  Return 

newValue

.

UnaryExpression

[Yield, Await]

 

:

UpdateExpression

[?Yield, ?Await]

delete

 

UnaryExpression

[?Yield, ?Await]

void

 

UnaryExpression

[?Yield, ?Await]

typeof

 

UnaryExpression

[?Yield, ?Await]

+

 

UnaryExpression

[?Yield, ?Await]

-

 

UnaryExpression

[?Yield, ?Await]

~

 

UnaryExpression

[?Yield, ?Await]

!

 

UnaryExpression

[?Yield, ?Await]

[+Await]

AwaitExpression

[?Yield]

13.4.3.1  Runtime Semantics: Evaluation

13.4.4  Prefix Increment Operator

13.4.4.1  Runtime Semantics: Evaluation

13.4.5  Prefix Decrement Operator

13.4.5.1  Runtime Semantics: Evaluation

13.5  Unary Operators

Syntax

332

UnaryExpression

 

:

 

delete

 

UnaryExpression

It is a Syntax Error if the 

UnaryExpression

 is contained in 

strict mode code

 and the derived 

UnaryExpression

 is

PrimaryExpression

 

:

 

IdentifierReference

 .

It is a Syntax Error if the derived 

UnaryExpression

 is 

PrimaryExpression

 

:

 

CoverParenthesizedExpressionAndArrowParameterList

 

and 

CoverParenthesizedExpressionAndArrowParameterList

 ultimately derives a phrase that, if used in place of 

UnaryExpression

, would produce a Syntax Error according to these rules. This rule is recursively applied.

NOTE

UnaryExpression

 

:

 

delete

 

UnaryExpression

1.  Let 

ref

 be the result of evaluating 

UnaryExpression

.

2. 

ReturnIfAbrupt

(

ref

).

3.  If 

ref

 is not a 

Reference Record

, return 

true

.

4.  If 

IsUnresolvableReference

(

ref

) is 

true

, then

a. 

Assert

ref

.[[Strict]] is 

false

.

b.  Return 

true

.

5.  If 

IsPropertyReference

(

ref

) is 

true

, then

a.  If 

IsSuperReference

(

ref

) is 

true

, throw a 

ReferenceError

 exception.

b.  Let 

baseObj

 be ! 

ToObject

(

ref

.[[Base]]).

c.  Let 

deleteStatus

 be ? 

baseObj

.[[Delete]](

ref

.[[ReferencedName]]).

d.  If 

deleteStatus

 is 

false

 and 

ref

.[[Strict]] is 

true

, throw a 

TypeError

 exception.

e.  Return 

deleteStatus

.

6.  Else,

a.  Let 

base

 be 

ref

.[[Base]].

b. 

Assert

base

 is an 

Environment Record

.

c.  Return ? 

base

.DeleteBinding(

ref

.[[ReferencedName]]).

NOTE 1

NOTE 2

The last rule means that expressions such as 

delete (((foo)))

delete (((foo)))

 produce early errors

because of recursive application of the first rule.

When a 

delete

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

delete

 operator occurs within 

strict mode code

 and the property to be deleted

has the attribute { [[Configurable]]: 

false

 } (or otherwise cannot be deleted), a 

TypeError

exception is thrown.

The object that may be created in step 

5.b

 is not accessible outside of the above abstract operation

and the 

ordinary object

 [[Delete]] internal method. An implementation might choose to avoid the

actual creation of that object.

13.5.1  The 

delete

delete

 Operator

13.5.1.1  Static Semantics: Early Errors

13.5.1.2  Runtime Semantics: Evaluation

333

UnaryExpression

 

:

 

void

 

UnaryExpression

1.  Let 

expr

 be the result of evaluating 

UnaryExpression

.

2.  Perform ? 

GetValue

(

expr

).

3.  Return 

undefined

.

NOTE

UnaryExpression

 

:

 

typeof

 

UnaryExpression

1.  Let 

val

 be the result of evaluating 

UnaryExpression

.

2.  If 

val

 is a 

Reference Record

, then

a.  If 

IsUnresolvableReference

(

val

) is 

true

, return 

"undefined"

.

3.  Set 

val

 to ? 

GetValue

(

val

).

4.  Return a String according to 

Table 37

.

Table 37: typeof Operator Results

Type of 

val

Result

Undefined

"undefined"

Null

"object"

Boolean

"boolean"

Number

"number"

String

"string"

Symbol

"symbol"

BigInt

"bigint"

Object (does not implement [[Call]])

"object"

Object (implements [[Call]])

"function"

NOTE

GetValue

 must be called even though its value is not used because it may have observable side-

effects.

An additional entry related to [[IsHTMLDDA]] Internal Slot can be found in 

B.3.7.3

.

13.5.2  The 

void

void

 Operator

13.5.2.1  Runtime Semantics: Evaluation

13.5.3  The 

typeof

typeof

 Operator

13.5.3.1  Runtime Semantics: Evaluation

13.5.4  Unary 

++

 Operator

334

NOTE

UnaryExpression

 

:

 

+

 

UnaryExpression

1.  Let 

expr

 be the result of evaluating 

UnaryExpression

.

2.  Return ? 

ToNumber

(? 

GetValue

(

expr

)).

NOTE

UnaryExpression

 

:

 

-

 

UnaryExpression

1.  Let 

expr

 be the result of evaluating 

UnaryExpression

.

2.  Let 

oldValue

 be ? 

ToNumeric

(? 

GetValue

(

expr

)).

3.  Let 

T

 be 

Type

(

oldValue

).

4.  Return ! 

T

::unaryMinus(

oldValue

).

UnaryExpression

 

:

 

~

 

UnaryExpression

1.  Let 

expr

 be the result of evaluating 

UnaryExpression

.

2.  Let 

oldValue

 be ? 

ToNumeric

(? 

GetValue

(

expr

)).

3.  Let 

T

 be 

Type

(

oldValue

).

4.  Return ! 

T

::bitwiseNOT(

oldValue

).

UnaryExpression

 

:

 

!

 

UnaryExpression

1.  Let 

expr

 be the result of evaluating 

UnaryExpression

.

2.  Let 

oldValue

 be ! 

ToBoolean

(? 

GetValue

(

expr

)).

3.  If 

oldValue

 is 

true

, return 

false

.

4.  Return 

true

.

The unary + operator converts its operand to Number type.

The unary 

--

 operator converts its operand to Number type and then negates it. Negating 

+0

𝔽

produces 

-0

𝔽

, and negating 

-0

𝔽

 produces 

+0

𝔽

.

13.5.4.1  Runtime Semantics: Evaluation

13.5.5  Unary 

--

 Operator

13.5.5.1  Runtime Semantics: Evaluation

13.5.6  Bitwise NOT Operator ( 

~~

 )

13.5.6.1  Runtime Semantics: Evaluation

13.5.7  Logical NOT Operator ( 

!!

 )

13.5.7.1  Runtime Semantics: Evaluation

13.6  Exponentiation Operator

335

ExponentiationExpression

[Yield, Await]

 

:

UnaryExpression

[?Yield, ?Await]

UpdateExpression

[?Yield, ?Await]

 

**

 

ExponentiationExpression

[?Yield, ?Await]

ExponentiationExpression

 

:

 

UpdateExpression

 

**

 

ExponentiationExpression

1.  Return ? 

EvaluateStringOrNumericBinaryExpression

(

UpdateExpression

**

**

ExponentiationExpression

).

MultiplicativeExpression

[Yield, Await]

 

:

ExponentiationExpression

[?Yield, ?Await]

MultiplicativeExpression

[?Yield, ?Await]

 

MultiplicativeOperator

 

ExponentiationExpression

[?Yield, ?Await]

MultiplicativeOperator

 

:

 

one of

*

 

/

 

%

NOTE

MultiplicativeExpression

 

:

 

MultiplicativeExpression

 

MultiplicativeOperator

 

ExponentiationExpression

1.  Let 

opText

 be the source text matched by 

MultiplicativeOperator

.

2.  Return ? 

EvaluateStringOrNumericBinaryExpression

(

MultiplicativeExpression

opText

ExponentiationExpression

).

AdditiveExpression

[Yield, Await]

 

:

MultiplicativeExpression

[?Yield, ?Await]

AdditiveExpression

[?Yield, ?Await]

 

+

 

MultiplicativeExpression

[?Yield, ?Await]

AdditiveExpression

[?Yield, ?Await]

 

-

 

MultiplicativeExpression

[?Yield, ?Await]

The 

**

 operator performs multiplication, producing the product of its operands.

The 

//

 operator performs division, producing the quotient of its operands.

The 

%%

 operator yields the remainder of its operands from an implied division.

Syntax

13.6.1  Runtime Semantics: Evaluation

13.7  Multiplicative Operators

Syntax

13.7.1  Runtime Semantics: Evaluation

13.8  Additive Operators

Syntax

336

NOTE

AdditiveExpression

 

:

 

AdditiveExpression

 

+

 

MultiplicativeExpression

1.  Return ? 

EvaluateStringOrNumericBinaryExpression

(

AdditiveExpression

++

MultiplicativeExpression

).

NOTE

AdditiveExpression

 

:

 

AdditiveExpression

 

-

 

MultiplicativeExpression

1.  Return ? 

EvaluateStringOrNumericBinaryExpression

(

AdditiveExpression

--

MultiplicativeExpression

).

ShiftExpression

[Yield, Await]

 

:

AdditiveExpression

[?Yield, ?Await]

ShiftExpression

[?Yield, ?Await]

 

<<

 

AdditiveExpression

[?Yield, ?Await]

ShiftExpression

[?Yield, ?Await]

 

>>

 

AdditiveExpression

[?Yield, ?Await]

ShiftExpression

[?Yield, ?Await]

 

>>>

 

AdditiveExpression

[?Yield, ?Await]

NOTE

ShiftExpression

 

:

 

ShiftExpression

 

<<

 

AdditiveExpression

1.  Return ? 

EvaluateStringOrNumericBinaryExpression

(

ShiftExpression

<<

<<

AdditiveExpression

).

The addition operator either performs string concatenation or numeric addition.

The 

--

 operator performs subtraction, producing the difference of its operands.

Performs a bitwise left shift operation on the left operand by the amount specified by the right
operand.

13.8.1  The Addition Operator ( 

++

 )

13.8.1.1  Runtime Semantics: Evaluation

13.8.2  The Subtraction Operator ( 

--

 )

13.8.2.1  Runtime Semantics: Evaluation

13.9  Bitwise Shift Operators

Syntax

13.9.1  The Left Shift Operator ( 

<<

<<

 )

13.9.1.1  Runtime Semantics: Evaluation

13.9.2  The Signed Right Shift Operator ( 

>>

>>

 )

337

NOTE

ShiftExpression

 

:

 

ShiftExpression

 

>>

 

AdditiveExpression

1.  Return ? 

EvaluateStringOrNumericBinaryExpression

(

ShiftExpression

>>

>>

AdditiveExpression

).

NOTE

ShiftExpression

 

:

 

ShiftExpression

 

>>>

 

AdditiveExpression

1.  Return ? 

EvaluateStringOrNumericBinaryExpression

(

ShiftExpression

>>>

>>>

AdditiveExpression

).

NOTE 1

RelationalExpression

[In, Yield, Await]

 

:

ShiftExpression

[?Yield, ?Await]

RelationalExpression

[?In, ?Yield, ?Await]

 

<

 

ShiftExpression

[?Yield, ?Await]

RelationalExpression

[?In, ?Yield, ?Await]

 

>

 

ShiftExpression

[?Yield, ?Await]

RelationalExpression

[?In, ?Yield, ?Await]

 

<=

 

ShiftExpression

[?Yield, ?Await]

RelationalExpression

[?In, ?Yield, ?Await]

 

>=

 

ShiftExpression

[?Yield, ?Await]

RelationalExpression

[?In, ?Yield, ?Await]

 

instanceof

 

ShiftExpression

[?Yield, ?Await]

[+In]

 

RelationalExpression

[+In, ?Yield, ?Await]

 

in

 

ShiftExpression

[?Yield, ?Await]

NOTE 2

RelationalExpression

 

:

 

RelationalExpression

 

<

 

ShiftExpression

1.  Let 

lref

 be the result of evaluating 

RelationalExpression

.

Performs a sign-filling bitwise right shift operation on the left operand by the amount specified
by the right operand.

Performs a zero-filling bitwise right shift operation on the left operand by the amount specified
by the right operand.

The result of evaluating a relational operator is always of type Boolean, reflecting whether the
relationship named by the operator holds between its two operands.

The 

[In]

 grammar parameter is needed to avoid confusing the 

in

in

 operator in a relational

expression with the 

in

in

 operator in a 

for

for

 statement.

13.9.2.1  Runtime Semantics: Evaluation

13.9.3  The Unsigned Right Shift Operator ( 

>>>

>>>

 )

13.9.3.1  Runtime Semantics: Evaluation

13.10  Relational Operators

Syntax

13.10.1  Runtime Semantics: Evaluation

338

2.  Let 

lval

 be ? 

GetValue

(

lref

).

3.  Let 

rref

 be the result of evaluating 

ShiftExpression

.

4.  Let 

rval

 be ? 

GetValue

(

rref

).

5.  Let 

r

 be the result of performing 

Abstract Relational Comparison

 

lval

 < 

rval

.

6. 

ReturnIfAbrupt

(

r

).

7.  If 

r

 is 

undefined

, return 

false

. Otherwise, return 

r

.

RelationalExpression

 

:

 

RelationalExpression

 

>

 

ShiftExpression

1.  Let 

lref

 be the result of evaluating 

RelationalExpression

.

2.  Let 

lval

 be ? 

GetValue

(

lref

).

3.  Let 

rref

 be the result of evaluating 

ShiftExpression

.

4.  Let 

rval

 be ? 

GetValue

(

rref

).

5.  Let 

r

 be the result of performing 

Abstract Relational Comparison

 

rval

 < 

lval

 with 

LeftFirst

 equal to 

false

.

6. 

ReturnIfAbrupt

(

r

).

7.  If 

r

 is 

undefined

, return 

false

. Otherwise, return 

r

.

RelationalExpression

 

:

 

RelationalExpression

 

<=

 

ShiftExpression

1.  Let 

lref

 be the result of evaluating 

RelationalExpression

.

2.  Let 

lval

 be ? 

GetValue

(

lref

).

3.  Let 

rref

 be the result of evaluating 

ShiftExpression

.

4.  Let 

rval

 be ? 

GetValue

(

rref

).

5.  Let 

r

 be the result of performing 

Abstract Relational Comparison

 

rval

 < 

lval

 with 

LeftFirst

 equal to 

false

.

6. 

ReturnIfAbrupt

(

r

).

7.  If 

r

 is 

true

 or 

undefined

, return 

false

. Otherwise, return 

true

.

RelationalExpression

 

:

 

RelationalExpression

 

>=

 

ShiftExpression

1.  Let 

lref

 be the result of evaluating 

RelationalExpression

.

2.  Let 

lval

 be ? 

GetValue

(

lref

).

3.  Let 

rref

 be the result of evaluating 

ShiftExpression

.

4.  Let 

rval

 be ? 

GetValue

(

rref

).

5.  Let 

r

 be the result of performing 

Abstract Relational Comparison

 

lval

 < 

rval

.

6. 

ReturnIfAbrupt

(

r

).

7.  If 

r

 is 

true

 or 

undefined

, return 

false

. Otherwise, return 

true

.

RelationalExpression

 

:

 

RelationalExpression

 

instanceof

 

ShiftExpression

1.  Let 

lref

 be the result of evaluating 

RelationalExpression

.

2.  Let 

lval

 be ? 

GetValue

(

lref

).

3.  Let 

rref

 be the result of evaluating 

ShiftExpression

.

4.  Let 

rval

 be ? 

GetValue

(

rref

).

5.  Return ? 

InstanceofOperator

(

lval

rval

).

RelationalExpression

 

:

 

RelationalExpression

 

in

 

ShiftExpression

1.  Let 

lref

 be the result of evaluating 

RelationalExpression

.

2.  Let 

lval

 be ? 

GetValue

(

lref

).

3.  Let 

rref

 be the result of evaluating 

ShiftExpression

.

4.  Let 

rval

 be ? 

GetValue

(

rref

).

339

5.  If 

Type

(

rval

) is not Object, throw a 

TypeError

 exception.

6.  Return ? 

HasProperty

(

rval

, ? 

ToPropertyKey

(

lval

)).

The abstract operation InstanceofOperator takes arguments 

V

 (an 

ECMAScript language value

) and 

target

 (an

ECMAScript language value

). It implements the generic algorithm for determining if 

V

 is an instance of 

target

 either

by consulting 

target

's 

@@hasInstance

 method or, if absent, determining whether the value of 

target

's 

"prototype"

property is present in 

V

's prototype chain. It performs the following steps when called:

1.  If 

Type

(

target

) is not Object, throw a 

TypeError

 exception.

2.  Let 

instOfHandler

 be ? 

GetMethod

(

target

@@hasInstance

).

3.  If 

instOfHandler

 is not 

undefined

, then

a.  Return ! 

ToBoolean

(? 

Call

(

instOfHandler

target

, « 

V

 »)).

4.  If 

IsCallable

(

target

) is 

false

, throw a 

TypeError

 exception.

5.  Return ? 

OrdinaryHasInstance

(

target

V

).

NOTE

NOTE

EqualityExpression

[In, Yield, Await]

 

:

RelationalExpression

[?In, ?Yield, ?Await]

EqualityExpression

[?In, ?Yield, ?Await]

 

==

 

RelationalExpression

[?In, ?Yield, ?Await]

EqualityExpression

[?In, ?Yield, ?Await]

 

!=

 

RelationalExpression

[?In, ?Yield, ?Await]

EqualityExpression

[?In, ?Yield, ?Await]

 

===

 

RelationalExpression

[?In, ?Yield, ?Await]

EqualityExpression

[?In, ?Yield, ?Await]

 

!==

 

RelationalExpression

[?In, ?Yield, ?Await]

EqualityExpression

 

:

 

EqualityExpression

 

==

 

RelationalExpression

1.  Let 

lref

 be the result of evaluating 

EqualityExpression

.

2.  Let 

lval

 be ? 

GetValue

(

lref

).

3.  Let 

rref

 be the result of evaluating 

RelationalExpression

.

4.  Let 

rval

 be ? 

GetValue

(

rref

).

5.  Return the result of performing 

Abstract Equality Comparison

 

rval

 == 

lval

.

EqualityExpression

 

:

 

EqualityExpression

 

!=

 

RelationalExpression

Steps 

4

 and 

5

 provide compatibility with previous editions of ECMAScript that did not use a

@@hasInstance

 method to define the 

instanceof

instanceof

 operator semantics. If an object does not

define or inherit 

@@hasInstance

 it uses the default 

instanceof

instanceof

 semantics.

The result of evaluating an equality operator is always of type Boolean, reflecting whether the
relationship named by the operator holds between its two operands.

13.10.2  InstanceofOperator ( 

V

target

 )

13.11  Equality Operators

Syntax

13.11.1  Runtime Semantics: Evaluation

340

1.  Let 

lref

 be the result of evaluating 

EqualityExpression

.

2.  Let 

lval

 be ? 

GetValue

(

lref

).

3.  Let 

rref

 be the result of evaluating 

RelationalExpression

.

4.  Let 

rval

 be ? 

GetValue

(

rref

).

5.  Let 

r

 be the result of performing 

Abstract Equality Comparison

 

rval

 == 

lval

.

6. 

ReturnIfAbrupt

(

r

).

7.  If 

r

 is 

true

, return 

false

. Otherwise, return 

true

.

EqualityExpression

 

:

 

EqualityExpression

 

===

 

RelationalExpression

1.  Let 

lref

 be the result of evaluating 

EqualityExpression

.

2.  Let 

lval

 be ? 

GetValue

(

lref

).

3.  Let 

rref

 be the result of evaluating 

RelationalExpression

.

4.  Let 

rval

 be ? 

GetValue

(

rref

).

5.  Return the result of performing 

Strict Equality Comparison

 

rval

 === 

lval

.

EqualityExpression

 

:

 

EqualityExpression

 

!==

 

RelationalExpression

1.  Let 

lref

 be the result of evaluating 

EqualityExpression

.

2.  Let 

lval

 be ? 

GetValue

(

lref

).

3.  Let 

rref

 be the result of evaluating 

RelationalExpression

.

4.  Let 

rval

 be ? 

GetValue

(

rref

).

5.  Let 

r

 be the result of performing 

Strict Equality Comparison

 

rval

 === 

lval

.

6. 

Assert

r

 is a normal completion.

7.  If 

r

.[[Value]] is 

true

, return 

false

. Otherwise, return 

true

.

NOTE 1

NOTE 2

NOTE 3

Given the above definition of equality:

String comparison can be forced by: 

`${a}` == `${b}`

`${a}` == `${b}`

.

Numeric comparison can be forced by: 

+a == +b

+a == +b

.

Boolean comparison can be forced by: 

!a == !b

!a == !b

.

The equality operators maintain the following invariants:

A != B

A != B

 is equivalent to 

!(A == B)

!(A == B)

.

A == B

A == B

 is equivalent to 

B == A

B == A

, except in the order of evaluation of 

AA

 and 

BB

.

The equality operator is not always transitive. For example, there might be two distinct String
objects, each representing the same String value; each String object would be considered equal to
the String value by the 

==

==

 operator, but the two String objects would not be equal to each other.

For example:

new String("a") == "a"

new String("a") == "a"

 and 

"a" == new String("a")

"a" == new String("a")

 are both 

true

.

new String("a") == new String("a")

new String("a") == new String("a")

 is 

false

.

341

NOTE 4

BitwiseANDExpression

[In, Yield, Await]

 

:

EqualityExpression

[?In, ?Yield, ?Await]

BitwiseANDExpression

[?In, ?Yield, ?Await]

 

&

 

EqualityExpression

[?In, ?Yield, ?Await]

BitwiseXORExpression

[In, Yield, Await]

 

:

BitwiseANDExpression

[?In, ?Yield, ?Await]

BitwiseXORExpression

[?In, ?Yield, ?Await]

 

^

 

BitwiseANDExpression

[?In, ?Yield, ?Await]

BitwiseORExpression

[In, Yield, Await]

 

:

BitwiseXORExpression

[?In, ?Yield, ?Await]

BitwiseORExpression

[?In, ?Yield, ?Await]

 

|

 

BitwiseXORExpression

[?In, ?Yield, ?Await]

BitwiseANDExpression

 

:

 

BitwiseANDExpression

 

&

 

EqualityExpression

1.  Return ? 

EvaluateStringOrNumericBinaryExpression

(

BitwiseANDExpression

&&

EqualityExpression

).

BitwiseXORExpression

 

:

 

BitwiseXORExpression

 

^

 

BitwiseANDExpression

1.  Return ? 

EvaluateStringOrNumericBinaryExpression

(

BitwiseXORExpression

^^

BitwiseANDExpression

).

BitwiseORExpression

 

:

 

BitwiseORExpression

 

|

 

BitwiseXORExpression

1.  Return ? 

EvaluateStringOrNumericBinaryExpression

(

BitwiseORExpression

||

BitwiseXORExpression

).

LogicalANDExpression

[In, Yield, Await]

 

:

BitwiseORExpression

[?In, ?Yield, ?Await]

LogicalANDExpression

[?In, ?Yield, ?Await]

 

&&

 

BitwiseORExpression

[?In, ?Yield, ?Await]

LogicalORExpression

[In, Yield, Await]

 

:

LogicalANDExpression

[?In, ?Yield, ?Await]

Comparison of Strings uses a simple equality test on sequences of code unit values. There is no
attempt to use the more complex, semantically oriented definitions of character or string equality
and collating order defined in the Unicode specification. Therefore Strings values that are
canonically equal according to the Unicode standard could test as unequal. In effect this
algorithm assumes that both Strings are already in normalized form.

13.12  Binary Bitwise Operators

Syntax

13.12.1  Runtime Semantics: Evaluation

13.13  Binary Logical Operators

Syntax

342

LogicalORExpression

[?In, ?Yield, ?Await]

 

||

 

LogicalANDExpression

[?In, ?Yield, ?Await]

CoalesceExpression

[In, Yield, Await]

 

:

CoalesceExpressionHead

[?In, ?Yield, ?Await]

 

??

 

BitwiseORExpression

[?In, ?Yield, ?Await]

CoalesceExpressionHead

[In, Yield, Await]

 

:

CoalesceExpression

[?In, ?Yield, ?Await]

BitwiseORExpression

[?In, ?Yield, ?Await]

ShortCircuitExpression

[In, Yield, Await]

 

:

LogicalORExpression

[?In, ?Yield, ?Await]

CoalesceExpression

[?In, ?Yield, ?Await]

NOTE

LogicalANDExpression

 

:

 

LogicalANDExpression

 

&&

 

BitwiseORExpression

1.  Let 

lref

 be the result of evaluating 

LogicalANDExpression

.

2.  Let 

lval

 be ? 

GetValue

(

lref

).

3.  Let 

lbool

 be ! 

ToBoolean

(

lval

).

4.  If 

lbool

 is 

false

, return 

lval

.

5.  Let 

rref

 be the result of evaluating 

BitwiseORExpression

.

6.  Return ? 

GetValue

(

rref

).

LogicalORExpression

 

:

 

LogicalORExpression

 

||

 

LogicalANDExpression

1.  Let 

lref

 be the result of evaluating 

LogicalORExpression

.

2.  Let 

lval

 be ? 

GetValue

(

lref

).

3.  Let 

lbool

 be ! 

ToBoolean

(

lval

).

4.  If 

lbool

 is 

true

, return 

lval

.

5.  Let 

rref

 be the result of evaluating 

LogicalANDExpression

.

6.  Return ? 

GetValue

(

rref

).

CoalesceExpression

 

:

 

CoalesceExpressionHead

 

??

 

BitwiseORExpression

1.  Let 

lref

 be the result of evaluating 

CoalesceExpressionHead

.

2.  Let 

lval

 be ? 

GetValue

(

lref

).

3.  If 

lval

 is 

undefined

 or 

null

, then

a.  Let 

rref

 be the result of evaluating 

BitwiseORExpression

.

b.  Return ? 

GetValue

(

rref

).

4.  Otherwise, return 

lval

.

The value produced by a 

&&

&&

 or 

||

||

 operator is not necessarily of type Boolean. The value

produced will always be the value of one of the two operand expressions.

13.13.1  Runtime Semantics: Evaluation

13.14  Conditional Operator ( 

? :

? :

 )

343

ConditionalExpression

[In, Yield, Await]

 

:

ShortCircuitExpression

[?In, ?Yield, ?Await]

ShortCircuitExpression

[?In, ?Yield, ?Await]

 

?

 

AssignmentExpression

[+In, ?Yield, ?Await]

 

:

AssignmentExpression

[?In, ?Yield, ?Await]

NOTE

ConditionalExpression

 

:

 

ShortCircuitExpression

 

?

 

AssignmentExpression

 

:

 

AssignmentExpression

1.  Let 

lref

 be the result of evaluating 

ShortCircuitExpression

.

2.  Let 

lval

 be ! 

ToBoolean

(? 

GetValue

(

lref

)).

3.  If 

lval

 is 

true

, then

a.  Let 

trueRef

 be the result of evaluating the first 

AssignmentExpression

.

b.  Return ? 

GetValue

(

trueRef

).

4.  Else,

a.  Let 

falseRef

 be the result of evaluating the second 

AssignmentExpression

.

b.  Return ? 

GetValue

(

falseRef

).

AssignmentExpression

[In, Yield, Await]

 

:

ConditionalExpression

[?In, ?Yield, ?Await]

[+Yield]

YieldExpression

[?In, ?Await]

ArrowFunction

[?In, ?Yield, ?Await]

AsyncArrowFunction

[?In, ?Yield, ?Await]

LeftHandSideExpression

[?Yield, ?Await]

 

=

 

AssignmentExpression

[?In, ?Yield, ?Await]

LeftHandSideExpression

[?Yield, ?Await]

 

AssignmentOperator

 

AssignmentExpression

[?In, ?Yield, ?Await]

LeftHandSideExpression

[?Yield, ?Await]

 

&&=

 

AssignmentExpression

[?In, ?Yield, ?Await]

LeftHandSideExpression

[?Yield, ?Await]

 

||=

 

AssignmentExpression

[?In, ?Yield, ?Await]

LeftHandSideExpression

[?Yield, ?Await]

 

??=

 

AssignmentExpression

[?In, ?Yield, ?Await]

AssignmentOperator

 

:

 

one of

*=

 

/=

 

%=

 

+=

 

-=

 

<<=

 

>>=

 

>>>=

 

&=

 

^=

 

|=

 

**=

The grammar for a 

ConditionalExpression

 in ECMAScript is slightly different from that in C and

Java, which each allow the second subexpression to be an 

Expression

 but restrict the third

expression to be a 

ConditionalExpression

. The motivation for this difference in ECMAScript is to

allow an assignment expression to be governed by either arm of a conditional and to eliminate
the confusing and fairly useless case of a comma expression as the centre expression.

Syntax

13.14.1  Runtime Semantics: Evaluation

13.15  Assignment Operators

Syntax

344

AssignmentExpression

 

:

 

LeftHandSideExpression

 

=

 

AssignmentExpression

If 

LeftHandSideExpression

 is an 

ObjectLiteral

 or an 

ArrayLiteral

, the following Early Error rules are applied:

It is a Syntax Error if 

LeftHandSideExpression

 is not 

covering

 an 

AssignmentPattern

.

All Early Error rules for 

AssignmentPattern

 and its derived productions also apply to the 

AssignmentPattern

 that

is 

covered

 by 

LeftHandSideExpression

.

If 

LeftHandSideExpression

 is neither an 

ObjectLiteral

 nor an 

ArrayLiteral

, the following Early Error rule is applied:

It is a Syntax Error if 

AssignmentTargetType

 of 

LeftHandSideExpression

 is not 

simple

.

AssignmentExpression

 

:

LeftHandSideExpression

 

AssignmentOperator

 

AssignmentExpression

LeftHandSideExpression

 

&&=

 

AssignmentExpression

LeftHandSideExpression

 

||=

 

AssignmentExpression

LeftHandSideExpression

 

??=

 

AssignmentExpression

It is a Syntax Error if 

AssignmentTargetType

 of 

LeftHandSideExpression

 is not 

simple

.

AssignmentExpression

 

:

 

LeftHandSideExpression

 

=

 

AssignmentExpression

1.  If 

LeftHandSideExpression

 is neither an 

ObjectLiteral

 nor an 

ArrayLiteral

, then

a.  Let 

lref

 be the result of evaluating 

LeftHandSideExpression

.

b. 

ReturnIfAbrupt

(

lref

).

c.  If 

IsAnonymousFunctionDefinition

(

AssignmentExpression

) and 

IsIdentifierRef

 of 

LeftHandSideExpression

are both 

true

, then

i.  Let 

rval

 be 

NamedEvaluation

 of 

AssignmentExpression

 with argument 

lref

.[[ReferencedName]].

d.  Else,

i.  Let 

rref

 be the result of evaluating 

AssignmentExpression

.

ii.  Let 

rval

 be ? 

GetValue

(

rref

).

e.  Perform ? 

PutValue

(

lref

rval

).

f.  Return 

rval

.

2.  Let 

assignmentPattern

 be the 

AssignmentPattern

 that is 

covered

 by 

LeftHandSideExpression

.

3.  Let 

rref

 be the result of evaluating 

AssignmentExpression

.

4.  Let 

rval

 be ? 

GetValue

(

rref

).

5.  Perform ? 

DestructuringAssignmentEvaluation

 of 

assignmentPattern

 using 

rval

 as the argument.

6.  Return 

rval

.

AssignmentExpression

 

:

 

LeftHandSideExpression

 

AssignmentOperator

 

AssignmentExpression

1.  Let 

lref

 be the result of evaluating 

LeftHandSideExpression

.

2.  Let 

lval

 be ? 

GetValue

(

lref

).

3.  Let 

rref

 be the result of evaluating 

AssignmentExpression

.

4.  Let 

rval

 be ? 

GetValue

(

rref

).

5.  Let 

assignmentOpText

 be the source text matched by 

AssignmentOperator

.

6.  Let 

opText

 be the sequence of Unicode code points associated with 

assignmentOpText

 in the following table:

13.15.1  Static Semantics: Early Errors

13.15.2  Runtime Semantics: Evaluation

345

 

 

 

 

 

 

 

Content      ..     41      42      43      44     ..