this
(
Expression )
The this
keyword evaluates to the value of the ThisBinding of the current execution
context.
An Identifier is evaluated by performing Identifier Resolution as specified in 10.3.1. The result of evaluating an Identifier is always a value of type Reference.
A Literal is evaluated as described in 7.8.
An array initialiser is an expression describing the initialisation of an Array object, written in a form of a literal. It is a list of zero or more expressions, each of which represents an array element, enclosed in square brackets. The elements need not be literals; they are evaluated each time the array initialiser is evaluated.
Array elements may be elided at the beginning, middle or end of the element list. Whenever a comma in the element list is not preceded by an AssignmentExpression (i.e., a comma at the beginning or after another comma), the missing array element contributes to the length of the Array and increases the index of subsequent elements. Elided array elements are not defined. If an element is elided at the end of an array, that element does not contribute to the length of the Array.
[
Elision_{opt} ]
[
ElementList ]
[
ElementList ,
Elision_{opt} ]
,
Elision_{opt} AssignmentExpression,
,
The production ArrayLiteral : [
Elision_{opt} ]
is evaluated as
follows:
new Array()
where
Array
is the standard built-in constructor with that name.The production ArrayLiteral : [
ElementList ]
is evaluated as follows:
The production ArrayLiteral : [
ElementList ,
Elision_{opt} ]
is evaluated as follows:
The production ElementList : Elision_{opt} AssignmentExpression is evaluated as follows:
new Array()
where
Array
is the standard built-in constructor with that name.The production ElementList : ElementList ,
Elision_{opt} AssignmentExpression is evaluated as follows:
The production Elision : ,
is evaluated as follows:
The production Elision : Elision ,
is evaluated as follows:
NOTE [[DefineOwnProperty]] is used to ensure that own properties are defined for the array even if the standard built-in Array prototype object has been modified in a manner that would preclude the creation of new own properties using [[Put]].
An object initialiser is an expression describing the initialisation of an Object, written in a form resembling a literal. It is a list of zero or more pairs of property names and associated values, enclosed in curly braces. The values need not be literals; they are evaluated each time the object initialiser is evaluated.
{
}
{
PropertyNameAndValueList }
{
PropertyNameAndValueList ,
}
,
PropertyAssignment:
AssignmentExpressionget
PropertyName (
)
{
FunctionBody }
set
PropertyName (
PropertySetParameterList )
{
FunctionBody }
The production ObjectLiteral : {
}
is evaluated as follows:
new Object()
where Object
is the
standard built-in constructor with that name.The productions ObjectLiteral : {
PropertyNameAndValueList }
and
ObjectLiteral : {
PropertyNameAndValueList ,} are evaluated as
follows:
The production PropertyNameAndValueList : PropertyAssignment is evaluated as follows:
new Object()
where
Object
is the standard built-in constructor with that name.The production
PropertyNameAndValueList :
PropertyNameAndValueList ,
PropertyAssignment
is evaluated as follows:
If the above steps would throw a SyntaxError then an implementation must treat the error as an early error (Clause 16).
The production PropertyAssignment : PropertyName :
AssignmentExpression is evaluated as
follows:
The production PropertyAssignment : get
PropertyName (
)
{
FunctionBody }
is evaluated as follows:
The production PropertyAssignment : set
PropertyName (
PropertySetParameterList )
{
FunctionBody }
is evaluated as follows:
It is a SyntaxError if the Identifier "eval"
or the Identifier "arguments"
occurs as the Identifier in a PropertySetParameterList of a PropertyAssignment that is contained in strict code or if its FunctionBody is strict code.
The production PropertyName : IdentifierName is evaluated as follows:
The production PropertyName : StringLiteral is evaluated as follows:
The production PropertyName : NumericLiteral is evaluated as follows:
The production PrimaryExpression : (
Expression )
is evaluated as follows:
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 parenthesised expressions.
[
Expression ]
.
IdentifierNamenew
MemberExpression Argumentsnew
NewExpression[
Expression ]
.
IdentifierName(
)
(
ArgumentList )
,
AssignmentExpressionProperties are accessed by name, using either the dot notation:
.
IdentifierName.
IdentifierNameor the bracket notation:
[
Expression ]
[
Expression ]
The dot notation is explained by the following syntactic conversion:
.
IdentifierNameis identical in its behaviour to
[
<identifier-name-string> ]
and similarly
.
IdentifierNameis identical in its behaviour to
[
<identifier-name-string> ]
where <identifier-name-string> is a string literal containing the same sequence of characters after processing of Unicode escape sequences as the IdentifierName.
The production MemberExpression : MemberExpression [
Expression ]
is evaluated as follows:
The production CallExpression : CallExpression [
Expression ]
is evaluated in exactly the same manner, except that the contained CallExpression is evaluated in
step 1.
The production NewExpression : new
NewExpression is evaluated as follows:
The production MemberExpression : new
MemberExpression Arguments is evaluated as
follows:
The production CallExpression : MemberExpression Arguments is evaluated as follows:
The production CallExpression : CallExpression Arguments is evaluated in exactly the same manner, except that the contained CallExpression is evaluated in step 1.
The evaluation of an argument list produces a List of values (see 8.8).
The production Arguments : (
)
is evaluated as follows:
The production Arguments : (
ArgumentList )
is evaluated as follows:
The production ArgumentList : AssignmentExpression is evaluated as follows:
The production ArgumentList : ArgumentList ,
AssignmentExpression is evaluated as
follows:
The production MemberExpression : FunctionExpression is evaluated as follows:
++
--
The production PostfixExpression : LeftHandSideExpression [no LineTerminator
here] ++
is evaluated as follows:
"eval"
or "arguments"
1
to oldValue, using the same rules as for
the +
operator (see 11.6.3).The production PostfixExpression : LeftHandSideExpression [no LineTerminator here]
--
is evaluated as follows:
"eval"
or "arguments"
delete
UnaryExpressionvoid
UnaryExpressiontypeof
UnaryExpression++
UnaryExpression--
UnaryExpression+
UnaryExpression-
UnaryExpression~
UnaryExpression!
UnaryExpressionThe production UnaryExpression : delete
UnaryExpression is evaluated as follows:
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.
The production UnaryExpression : void
UnaryExpression is evaluated as follows:
NOTE GetValue must be called even though its value is not used because it may have observable side-effects.
The production UnaryExpression : typeof
UnaryExpression is evaluated as follows:
"undefined"
.Type of val | Result |
---|---|
Undefined | "undefined" |
Null | "object" |
Boolean | "boolean" |
Number | "number" |
String | "string" |
Object (native and does not implement [[Call]]) | "object" |
Object (native or host and does implement [[Call]]) | "function" |
Object (host and does not implement [[Call]]) | Implementation-defined except may not be "undefined" , "boolean" , "number ", or "string". |
The production UnaryExpression : ++
UnaryExpression is evaluated as follows:
"eval"
or "arguments"
1
to oldValue, using the same rules as for
the +
operator (see 11.6.3).The production UnaryExpression : --
UnaryExpression is evaluated as follows:
"eval"
or "arguments"
1
from oldValue, using the same rules
as for the -
operator (see 11.6.3).The unary + operator converts its operand to Number type.
The production UnaryExpression : +
UnaryExpression is evaluated as follows:
The unary -
operator converts its operand to Number type and then negates it. Note that negating +0
produces −0, and negating −0 produces +0.
The production UnaryExpression : -
UnaryExpression is evaluated as follows:
The production UnaryExpression : ~
UnaryExpression is evaluated as follows:
The production UnaryExpression : !
UnaryExpression is evaluated as follows:
*
UnaryExpression/
UnaryExpression%
UnaryExpressionThe production MultiplicativeExpression : MultiplicativeExpression @
UnaryExpression , where @
stands for one of the operators in the above definitions, is evaluated as follows:
The *
operator performs multiplication, producing the product of its operands. Multiplication is
commutative. Multiplication is not always associative in ECMAScript, because of finite precision.
The result of a floating-point multiplication is governed by the rules of IEEE 754 binary double-precision arithmetic:
If either operand is NaN, the result is NaN.
The sign of the result is positive if both operands have the same sign, negative if the operands have different signs.
Multiplication of an infinity by a zero results in NaN.
Multiplication of an infinity by an infinity results in an infinity. The sign is determined by the rule already stated above.
Multiplication of an infinity by a finite nonzero value results in a signed infinity. The sign is determined by the rule already stated above.
In the remaining cases, where neither an infinity or NaN is involved, the product is computed and rounded to the nearest representable value using IEEE 754 round-to-nearest mode. If the magnitude is too large to represent, the result is then an infinity of appropriate sign. If the magnitude is too small to represent, the result is then a zero of appropriate sign. The ECMAScript language requires support of gradual underflow as defined by IEEE 754.
The /
operator performs division, producing the
quotient of its operands. The left operand is the dividend
and the right operand is the divisor. ECMAScript does not perform
integer division. The operands and result of all division
operations are double-precision floating-point numbers. The result
of division is determined by the specification of IEEE
754 arithmetic:
If either operand is NaN, the result is NaN.
The sign of the result is positive if both operands have the same sign, negative if the operands have different signs.
Division of an infinity by an infinity results in NaN.
Division of an infinity by a zero results in an infinity. The sign is determined by the rule already stated above.
Division of an infinity by a nonzero finite value results in a signed infinity. The sign is determined by the rule already stated above.
Division of a finite value by an infinity results in zero. The sign is determined by the rule already stated above.
Division of a zero by a zero results in NaN; division of zero by any other finite value results in zero, with the sign determined by the rule already stated above.
Division of a nonzero finite value by a zero results in a signed infinity. The sign is determined by the rule already stated above.
In the remaining cases, where neither an infinity, nor a zero, nor NaN is involved, the quotient is computed and rounded to the nearest representable value using IEEE 754 round-to-nearest mode. If the magnitude is too large to represent, the operation overflows; the result is then an infinity of appropriate sign. If the magnitude is too small to represent, the operation underflows and the result is a zero of the appropriate sign. The ECMAScript language requires support of gradual underflow as defined by IEEE 754.
The %
operator yields the remainder of its operands from an implied division; the left operand is the
dividend and the right operand is the divisor.
NOTE In C and C++, the remainder operator accepts only integral operands; in ECMAScript, it also accepts floating-point operands.
The result of a floating-point remainder operation as computed by the %
operator is not the same as the
“remainder” operation defined by IEEE 754. The IEEE 754 “remainder” operation computes the remainder
from a rounding division, not a truncating division, and so its behaviour is not analogous to that of the usual integer
remainder operator. Instead the ECMAScript language defines %
on floating-point operations to behave in a
manner analogous to that of the Java integer remainder operator; this may be compared with the C library function fmod.
The result of an ECMAScript floating-point remainder operation is determined by the rules of IEEE arithmetic:
If either operand is NaN, the result is NaN.
The sign of the result equals the sign of the dividend.
If the dividend is an infinity, or the divisor is a zero, or both, the result is NaN.
If the dividend is finite and the divisor is an infinity, the result equals the dividend.
If the dividend is a zero and the divisor is nonzero and finite, the result is the same as the dividend.
In the remaining cases, where neither an infinity, nor a zero, nor NaN is involved, the floating-point remainder r from a dividend n and a divisor d is defined by the mathematical relation r = n − (d × q) where q is an integer that is negative only if n/d is negative and positive only if n/d is positive, and whose magnitude is as large as possible without exceeding the magnitude of the true mathematical quotient of n and d. r is computed and rounded to the nearest representable value using IEEE 754 round-to-nearest mode.
+
MultiplicativeExpression-
MultiplicativeExpressionThe addition operator either performs string concatenation or numeric addition.
The production AdditiveExpression : AdditiveExpression +
MultiplicativeExpression is
evaluated as follows:
NOTE 1 No hint is provided in the calls to ToPrimitive in steps 5 and 6. All native ECMAScript objects except Date objects handle the absence of a hint as if the hint Number were given; Date objects handle the absence of a hint as if the hint String were given. Host objects may handle the absence of a hint in some other manner.
NOTE 2 Step 7 differs from step 3 of the comparison algorithm for the relational operators (11.8.5), by using the logical-or operation instead of the logical-and operation.
The production AdditiveExpression : AdditiveExpression -
MultiplicativeExpression is
evaluated as follows:
The +
operator performs addition when applied to two operands of numeric type, producing the sum of the
operands. The -
operator performs subtraction, producing the difference of two numeric operands.
Addition is a commutative operation, but not always associative.
The result of an addition is determined using the rules of IEEE 754 binary double-precision arithmetic:
If either operand is NaN, the result is NaN.
The sum of two infinities of opposite sign is NaN.
The sum of two infinities of the same sign is the infinity of that sign.
The sum of an infinity and a finite value is equal to the infinite operand.
The sum of two negative zeroes is −0. The sum of two positive zeroes, or of two zeroes of opposite sign, is +0.
The sum of a zero and a nonzero finite value is equal to the nonzero operand.
The sum of two nonzero finite values of the same magnitude and opposite sign is +0.
In the remaining cases, where neither an infinity, nor a zero, nor NaN is involved, and the operands have the same sign or have different magnitudes, the sum is computed and rounded to the nearest representable value using IEEE 754 round-to-nearest mode. If the magnitude is too large to represent, the operation overflows and the result is then an infinity of appropriate sign. The ECMAScript language requires support of gradual underflow as defined by IEEE 754.
The -
operator performs subtraction when applied to two operands of numeric type, producing the difference
of its operands; the left operand is the minuend and the right operand is the subtrahend. Given numeric operands
a and b, it is always the case that a–b produces the same
result as a +(–b).
<<
AdditiveExpression>>
AdditiveExpression>>>
AdditiveExpressionPerforms a bitwise left shift operation on the left operand by the amount specified by the right operand.
The production ShiftExpression : ShiftExpression <<
AdditiveExpression is
evaluated as follows:
Performs a sign-filling bitwise right shift operation on the left operand by the amount specified by the right operand.
The production ShiftExpression : ShiftExpression >>
AdditiveExpression is
evaluated as follows:
Performs a zero-filling bitwise right shift operation on the left operand by the amount specified by the right operand.
The production ShiftExpression : ShiftExpression >>>
AdditiveExpression is
evaluated as follows:
<
ShiftExpression>
ShiftExpression<=
ShiftExpression>=
ShiftExpressioninstanceof
ShiftExpressionin
ShiftExpression<
ShiftExpression>
ShiftExpression<=
ShiftExpression>=
ShiftExpressioninstanceof
ShiftExpressionNOTE The “NoIn” variants are needed to avoid confusing the in operator in a relational expression with the in operator in a for statement.
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 RelationalExpressionNoIn productions are evaluated in the same manner as the RelationalExpression productions except that the contained RelationalExpressionNoIn is evaluated instead of the contained RelationalExpression.
The production RelationalExpression : RelationalExpression <
ShiftExpression is
evaluated as follows:
The production RelationalExpression : RelationalExpression >
ShiftExpression is evaluated as follows:
The production RelationalExpression : RelationalExpression <=
ShiftExpression is evaluated as follows:
The production RelationalExpression : RelationalExpression >=
ShiftExpression is evaluated as follows:
The comparison x < y, where x and y are values, produces true, false, or undefined (which indicates that at least one operand is NaN). In addition to x and y the algorithm takes a Boolean flag named LeftFirst as a parameter. The flag is used to control the order in which operations with potentially visible side-effects are performed upon x and y. It is necessary because ECMAScript specifies left to right evaluation of expressions. The default value of LeftFirst is true and indicates that the x parameter corresponds to an expression that occurs to the left of the y parameter’s corresponding expression. If LeftFirst is false, the reverse is the case and operations must be performed upon y before x. Such a comparison is performed as follows:
NOTE 1 Step 3 differs from step 7 in the algorithm for the addition operator +
(11.6.1) in using and instead of or.
NOTE 2 The comparison of Strings uses a simple lexicographic ordering 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 String 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 normalised form. Also, note that for strings containing supplementary characters, lexicographic ordering on sequences of UTF-16 code unit values differs from that on sequences of code point values.
The production RelationalExpression : RelationalExpression instanceof
ShiftExpression is
evaluated as follows:
The production RelationalExpression : RelationalExpression in
ShiftExpression is evaluated
as follows:
==
RelationalExpression!=
RelationalExpression===
RelationalExpression!==
RelationalExpression==
RelationalExpressionNoIn!=
RelationalExpressionNoIn===
RelationalExpressionNoIn!==
RelationalExpressionNoInThe result of evaluating an equality operator is always of type Boolean, reflecting whether the relationship named by the operator holds between its two operands.
The EqualityExpressionNoIn productions are evaluated in the same manner as the EqualityExpression productions except that the contained EqualityExpressionNoIn and RelationalExpressionNoIn are evaluated instead of the contained EqualityExpression and RelationalExpression, respectively.
The production EqualityExpression : EqualityExpression ==
RelationalExpression is evaluated as follows:
The production EqualityExpression : EqualityExpression !=
RelationalExpression is evaluated as follows:
The comparison x == y, where x and y are values, produces true or false. Such a comparison is performed as follows:
NOTE 1 Given the above definition of equality:
"" + a == "" + b
.+a == +b
.!a == !b
.NOTE 2 The equality operators maintain the following invariants:
A
!=
B
is equivalent to !(A
==
B)
.A
==
B
is equivalent to B
==
A
, except
in the order of evaluation of A
and B
.NOTE 3 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"
and "a"
==
new
String("a")
are both true.new String("a")
==
new String("a")
is false.NOTE 4 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 normalised form.
The production EqualityExpression : EqualityExpression ===
RelationalExpression is evaluated as follows:
The production EqualityExpression : EqualityExpression !==
RelationalExpression is evaluated as follows:
The comparison x === y, where x and y are values, produces true or false. Such a comparison is performed as follows:
NOTE This algorithm differs from the SameValue Algorithm (9.12) in its treatment of signed zeroes and NaNs.
&
EqualityExpression&
EqualityExpressionNoIn^
BitwiseANDExpression^
BitwiseANDExpressionNoIn|
BitwiseXORExpression|
BitwiseXORExpressionNoInThe production A : A @ B, where @ is one of the bitwise operators in the productions above, is evaluated as follows:
&&
BitwiseORExpression&&
BitwiseORExpressionNoIn||
LogicalANDExpression||
LogicalANDExpressionNoInThe production LogicalANDExpression : LogicalANDExpression &&
BitwiseORExpression is
evaluated as follows:
The production LogicalORExpression : LogicalORExpression ||
LogicalANDExpression is
evaluated as follows:
The LogicalANDExpressionNoIn and LogicalORExpressionNoIn productions are evaluated in the same manner as the LogicalANDExpression and LogicalORExpression productions except that the contained LogicalANDExpressionNoIn, BitwiseORExpressionNoIn and LogicalORExpressionNoIn are evaluated instead of the contained LogicalANDExpression, BitwiseORExpression and LogicalORExpression, respectively.
NOTE 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.
?
AssignmentExpression :
AssignmentExpression?
AssignmentExpression :
AssignmentExpressionNoInThe production ConditionalExpression : LogicalORExpression ?
AssignmentExpression :
AssignmentExpression is evaluated as follows:
The ConditionalExpressionNoIn production is evaluated in the same manner as the ConditionalExpression production except that the contained LogicalORExpressionNoIn, AssignmentExpression and AssignmentExpressionNoIn are evaluated instead of the contained LogicalORExpression, first AssignmentExpression and second AssignmentExpression, respectively.
NOTE The grammar for a ConditionalExpression in ECMAScript is a little bit 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.
=
AssignmentExpression=
AssignmentExpressionNoIn*= | /= | %= | += | -= | <<= | >>= | >>>= | &= | ^= | |= |
The AssignmentExpressionNoIn productions are evaluated in the same manner as the AssignmentExpression productions except that the contained ConditionalExpressionNoIn and AssignmentExpressionNoIn are evaluated instead of the contained ConditionalExpression and AssignmentExpression, respectively.
The production AssignmentExpression : LeftHandSideExpression =
AssignmentExpression is
evaluated as follows:
"eval"
or "arguments"
NOTE When an assignment occurs within strict mode code, its LeftHandSide must not evaluate to an unresolvable reference. If it does a ReferenceError exception is thrown upon assignment. The LeftHandSide also may not be a reference to a data property with the attribute value {[[Writable]]:false}, to an accessor property with the attribute value {[[Set]]:undefined}, nor to a non-existent property of an object whose [[Extensible]] internal property has the value false. In these cases a TypeError exception is thrown.
The production AssignmentExpression : LeftHandSideExpression AssignmentOperator AssignmentExpression , where AssignmentOperator is @=
and @
represents one of the operators indicated above, is evaluated as follows:
"eval"
or "arguments"
NOTE See NOTE 11.13.1.
,
AssignmentExpression,
AssignmentExpressionNoInThe production Expression : Expression ,
AssignmentExpression is evaluated as
follows:
The ExpressionNoIn production is evaluated in the same manner as the Expression production except that the contained ExpressionNoIn and AssignmentExpressionNoIn are evaluated instead of the contained Expression and AssignmentExpression, respectively.
NOTE GetValue must be called even though its value is not used because it may have observable side-effects.