‟Ex igne vita”
Syntax
PrimaryExpression :
this
Identifier
Literal
ArrayLiteral
ObjectLiteral(
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.
Syntax
ArrayLiteral :
[
Elisionopt
]
ElementList
[
]
ElementList , Elisionopt
[
]
ElementList :
Elisionopt
AssignmentExpression
ElementList ,
Elisionopt
AssignmentExpression
Elision :
,
Elision ,
Semantics
The
production ArrayLiteral
: [
Elisionopt
]
is
evaluated as follows:
Let
array be the result of creating a new object as if by the
expression new Array()
where
Array
is the standard built-in constructor with that
name.
Let pad be the result of evaluating Elision; if not present, use the numeric value zero.
Call
the [[Put]] internal method of array with arguments
"
length
"
,
pad, and false.
Return array.
The
production ArrayLiteral
: [
ElementList
]
is
evaluated as follows:
Return the result of evaluating ElementList.
The
production ArrayLiteral
: [
ElementList
,
Elisionopt
]
is
evaluated as follows:
Let array be the result of evaluating ElementList.
Let pad be the result of evaluating Elision; if not present, use the numeric value zero.
Let
len be the result of calling the [[Get]] internal method of
array with argument "
length
"
.
Call
the [[Put]] internal method of array with arguments
"
length
"
,
ToUint32(pad+len), and false.
Return array.
The
production ElementList
: Elisionopt
AssignmentExpression
is evaluated as follows:
Let
array be the result of creating a new object as if by the
expression new Array()
where
Array
is the standard built-in constructor with that
name.
Let firstIndex be the result of evaluating Elision; if not present, use the numeric value zero.
Let initResult be the result of evaluating AssignmentExpression.
Let initValue be GetValue(initResult).
Call the [[DefineOwnProperty]] internal method of array with arguments ToString(firstIndex), the Property Descriptor { [[Value]]: initValue, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, and false.
Return array.
The
production ElementList
: ElementList
, Elisionopt
AssignmentExpression
is evaluated as follows:
Let array be the result of evaluating ElementList.
Let pad be the result of evaluating Elision; if not present, use the numeric value zero.
Let initResult be the result of evaluating AssignmentExpression.
Let initValue be GetValue(initResult).
Let
len be the result of calling the [[Get]] internal method of
array with argument "
length
"
.
Call the [[DefineOwnProperty]] internal method of array with arguments ToString(ToUint32((pad+len)) and the Property Descriptor { [[Value]]: initValue, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, and false.
Return array.
The production Elision : , is evaluated as follows:
Return the numeric value 1.
The production Elision : Elision , is evaluated as follows:
Let preceding be the result of evaluating Elision.
Return preceding+1.
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.
Syntax
ObjectLiteral :
{
}
{
PropertyNameAndValueList
}
PropertyNameAndValueList
{
,
}
PropertyNameAndValueList :
PropertyAssignment
PropertyNameAndValueList
,
PropertyAssignment
PropertyAssignment :
PropertyName :
AssignmentExpressionget
PropertyName (
)
{
FunctionBody }
set
PropertyName (
PropertySetParameterList )
{
FunctionBody }
PropertyName :
IdentifierName
StringLiteral
NumericLiteral
PropertySetParameterList :
Identifier
Semantics
The
production ObjectLiteral
: {
}
is
evaluated as follows:
Return
a new object created as if by the expression new
Object()
where Object
is the standard built-in constructor with that name.
The
productions ObjectLiteral
: {
PropertyNameAndValueList
}
and
ObjectLiteral
: {
PropertyNameAndValueList
,
}
are evaluated as follows:
Return the result of evaluating PropertyNameAndValueList.
The production PropertyNameAndValueList : PropertyAssignment is evaluated as follows:
Let
obj be the result of creating a new object as if by the
expression new Object()
where Object
is the standard built-in constructor with that name.
Let propId be the result of evaluating PropertyAssignment.
Call the [[DefineOwnProperty]] internal method of obj with arguments propId.name, propId.descriptor, and false.
Return obj.
The
production
PropertyNameAndValueList
: PropertyNameAndValueList
, PropertyAssignment
is
evaluated as follows:
Let obj be the result of evaluating PropertyNameAndValueList.
Let propId be the result of evaluating PropertyAssignment.
Let previous be the result of calling the [[GetOwnProperty]] internal method of obj with argument propId.name.
If previous is not undefined then throw a SyntaxError exception if any of the following conditions are true
This production is contained in strict code and IsDataDescriptor(previous) is true and IsDataDescriptor(propId.descriptor) is true.
IsDataDescriptor(previous) is true and IsAccessorDescriptor(propId.descriptor) is true.
IsAccessorDescriptor(previous) is true and IsDataDescriptor(propId.descriptor) is true.
IsAccessorDescriptor(previous) is true and IsAccessorDescriptor(propId.descriptor) is true and either both previous and propId.descriptor have [[Get]] fields or both previous and propId.descriptor have [[Set]] fields
Call the [[DefineOwnProperty]] internal method of obj with arguments propId.name, propId.descriptor, and false.
Return obj.
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:
Let propName be the result of evaluating PropertyName.
Let exprValue be the result of evaluating AssignmentExpression.
Let propValue be GetValue(exprValue).
Let desc be the Property Descriptor{[[Value]]: propValue, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}
Return Property Identifier (propName, desc).
The
production PropertyAssignment
: get
PropertyName (
) {
FunctionBody
}
is
evaluated as follows:
Let propName be the result of evaluating PropertyName.
Let closure be the result of creating a new Function object as specified in 13.2 with an empty parameter list and body specified by FunctionBody. Pass in the LexicalEnvironment of the running execution context as the Scope. Pass in true as the Strict flag if the PropertyAssignment is contained in strict code or if its FunctionBody is strict code.
Let desc be the Property Descriptor{[[Get]]: closure, [[Enumerable]]: true, [[Configurable]]: true}
Return Property Identifier (propName, desc).
The
production PropertyAssignment
: set
PropertyName (
PropertySetParameterList
)
{
FunctionBody
}
is evaluated as
follows:
Let propName be the result of evaluating PropertyName.
Let closure be the result of creating a new Function object as specified in 13.2 with parameters specified by PropertySetParameterList and body specified by FunctionBody. Pass in the LexicalEnvironment of the running execution context as the Scope. Pass in true as the Strict flag if the PropertyAssignment is contained in strict code or if its FunctionBody is strict code.
Let desc be the Property Descriptor{[[Set]]: closure, [[Enumerable]]: true, [[Configurable]]: true}
Return Property Identifier (propName, desc).
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:
Return the String value containing the same sequence of characters as the IdentifierName.
The production PropertyName : StringLiteral is evaluated as follows:
Return the SV of the StringLiteral.
The production PropertyName : NumericLiteral is evaluated as follows:
Let nbr be the result of forming the value of the NumericLiteral.
Return ToString(nbr).
The
production PrimaryExpression
: (
Expression )
is evaluated as follows:
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 parenthesised expressions.
Syntax
MemberExpression :
PrimaryExpression
FunctionExpression
MemberExpression [
Expression ]
MemberExpression .
IdentifierNamenew
MemberExpression
Arguments
NewExpression :
MemberExpression
NewExpression
new
CallExpression :
MemberExpression
Arguments
CallExpression
Arguments
CallExpression [
Expression ]
CallExpression .
IdentifierName
Arguments :
(
)
ArgumentList
()
ArgumentList :
AssignmentExpression
ArgumentList ,
AssignmentExpression
LeftHandSideExpression :
NewExpression
CallExpression
Properties are accessed by name, using either the dot notation:
MemberExpression .
IdentifierName
CallExpression .
IdentifierName
or the bracket notation:
MemberExpression [
Expression ]
CallExpression [
Expression ]
The dot notation is explained by the following syntactic conversion:
MemberExpression .
IdentifierName
is identical in its behaviour to
MemberExpression [
<identifier-name-string> ]
and similarly
CallExpression .
IdentifierName
is identical in its behaviour to
CallExpression [
<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:
Let baseReference be the result of evaluating MemberExpression.
Let baseValue be GetValue(baseReference).
Let propertyNameReference be the result of evaluating Expression.
Let propertyNameValue be GetValue(propertyNameReference).
Call CheckObjectCoercible(baseValue).
Let propertyNameString be ToString(propertyNameValue).
If the syntactic production that is being evaluated is contained in strict mode code, let strict be true, else let strict be false.
Return a value of type Reference whose base value is baseValue and whose referenced name is propertyNameString, and whose strict mode flag is strict.
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:
Let ref be the result of evaluating NewExpression.
Let constructor be GetValue(ref).
If Type(constructor) is not Object, throw a TypeError exception.
If constructor does not implement the [[Construct]] internal method, throw a TypeError exception.
Return the result of calling the [[Construct]] internal method on constructor, providing no arguments (that is, an empty list of arguments).
The
production MemberExpression
: new
MemberExpression
Arguments is
evaluated as follows:
Let ref be the result of evaluating MemberExpression.
Let constructor be GetValue(ref).
Let argList be the result of evaluating Arguments, producing an internal list of argument values (11.2.4).
If Type(constructor) is not Object, throw a TypeError exception.
If constructor does not implement the [[Construct]] internal method, throw a TypeError exception.
Return the result of calling the [[Construct]] internal method on constructor, providing the list argList as the argument values.
The production CallExpression : MemberExpression Arguments is evaluated as follows:
Let ref be the result of evaluating MemberExpression.
Let func be GetValue(ref).
Let argList be the result of evaluating Arguments, producing an internal list of argument values (see 11.2.4).
If IsCallable(func) is false, throw a TypeError exception.
If Type(ref) is Reference, then
If IsPropertyReference(ref) is true, then
Let thisValue be GetBase(ref).
Else, the base of ref is an Environment Record
Let thisValue be the result of calling the ImplicitThisValue concrete method of GetBase(ref).
Else, Type(ref) is not Reference.
Let thisValue be undefined.
Return the result of calling the [[Call]] internal method on func, providing thisValue as the this value and providing the list argList as the argument values.
The production CallExpression : CallExpression Arguments is evaluated in exactly the same manner, except that the contained CallExpression is evaluated in step 1.
NOTE The returned result will never be of type Reference if func is a native ECMAScript object. Whether calling a host object can return a value of type Reference is implementation-dependent. If a value of type Reference is returned, it must be a non-strict Property Reference.
The evaluation of an argument list produces a List of values (see 8.8).
The
production Arguments :
( )
is evaluated
as follows:
Return an empty List.
The
production Arguments : (
ArgumentList
)
is evaluated as follows:
Return the result of evaluating ArgumentList.
The
production ArgumentList :
AssignmentExpression
is evaluated as follows:
Let ref be the result of evaluating AssignmentExpression.
Let arg be GetValue(ref).
Return a List whose sole item is arg.
The
production ArgumentList : ArgumentList
,
AssignmentExpression
is evaluated as follows:
Let precedingArgs be the result of evaluating ArgumentList.
Let ref be the result of evaluating AssignmentExpression.
Let arg be GetValue(ref).
Return a List whose length is one greater than the length of precedingArgs and whose items are the items of precedingArgs, in order, followed at the end by arg which is the last item of the new list.
The production MemberExpression : FunctionExpression is evaluated as follows:
Return the result of evaluating FunctionExpression.
Syntax
PostfixExpression :
LeftHandSideExpression
LeftHandSideExpression
[no LineTerminator here]
++
LeftHandSideExpression
[no LineTerminator here]
--
The
production PostfixExpression
: LeftHandSideExpression
[no LineTerminator here]
++
is evaluated as follows:
Let lhs be the result of evaluating LeftHandSideExpression.
Throw a SyntaxError exception if the following conditions are all true:
IsStrictReference(lhs) is true
Type(GetBase(lhs)) is Environment Record
GetReferencedName(lhs)
is either "eval"
or "arguments"
Let
newValue be the result of adding the value 1
to oldValue, using the same rules as for the +
operator (see 11.6.3).
Call PutValue(lhs, newValue).
Return oldValue.
The
production PostfixExpression
: LeftHandSideExpression
[no LineTerminator here]
--
is
evaluated as follows:
Let lhs be the result of evaluating LeftHandSideExpression.
Throw a SyntaxError exception if the following conditions are all true:
IsStrictReference(lhs) is true
Type(GetBase(lhs)) is Environment Record
GetReferencedName(lhs)
is either "eval"
or "arguments"
Let
newValue be the result of subtracting the value 1
from oldValue, using the same rules as for the -
operator (11.6.3).
Call PutValue(lhs, newValue).
Return oldValue.
Syntax
UnaryExpression :
PostfixExpression
UnaryExpression
delete
void
UnaryExpressiontypeof
UnaryExpression
UnaryExpression
++--
UnaryExpression+
UnaryExpression-
UnaryExpression~
UnaryExpression!
UnaryExpression
The
production UnaryExpression
: delete
UnaryExpression is evaluated as follows:
Let ref be the result of evaluating UnaryExpression.
If IsUnresolvableReference(ref) then,
If IsStrictReference(ref) is true, throw a SyntaxError exception.
Else, return true.
If IsPropertyReference(ref) is true, then
Return the result of calling the [[Delete]] internal method on ToObject(GetBase(ref)) providing GetReferencedName(ref) and IsStrictReference(ref) as the arguments.
Else, ref is a Reference to an Environment Record binding, so
If IsStrictReference(ref) is true, throw a SyntaxError exception.
Let bindings be GetBase(ref).
Return the result of calling the DeleteBinding concrete method of bindings, providing GetReferencedName(ref) as the argument.
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:
Let expr be the result of evaluating UnaryExpression.
Call GetValue(expr).
Return undefined.
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:
Let val be the result of evaluating UnaryExpression.
If Type(val) is Reference, then
If
IsUnresolvableReference(val) is true, return
"undefined"
.
Let val be GetValue(val).
Return a String determined by Type(val) according to Table 20.
Type of val |
Result |
Undefined |
|
Null |
|
Boolean |
|
Number |
|
String |
|
Object (native and does not implement [[Call]]) |
|
Object (native or host and does implement [[Call]]) |
|
Object (host and does not implement [[Call]]) |
Implementation-defined
except may not be |
The
production UnaryExpression : ++
UnaryExpression
is evaluated as follows:
Let expr be the result of evaluating UnaryExpression.
Throw a SyntaxError exception if the following conditions are all true:
IsStrictReference(expr) is true
Type(GetBase(expr)) is Environment Record
GetReferencedName(expr)
is either "eval"
or "arguments"
Let
newValue be the result of adding the value 1
to oldValue, using the same rules as for the +
operator (see 11.6.3).
Call PutValue(expr, newValue).
Return newValue.
The
production UnaryExpression : --
UnaryExpression
is evaluated as follows:
Let expr be the result of evaluating UnaryExpression.
Throw a SyntaxError exception if the following conditions are all true:
IsStrictReference(expr) is true
Type(GetBase(expr)) is Environment Record
GetReferencedName(expr)
is either "eval"
or "arguments"
Let
newValue be the result of subtracting the value 1
from oldValue, using the same rules as for the -
operator (see 11.6.3).
Call PutValue(expr, newValue).
Return newValue.
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:
Let expr be the result of evaluating UnaryExpression.
If oldValue is NaN, return NaN.
Return the result of negating oldValue; that is, compute a Number with the same magnitude but opposite sign.
The
production UnaryExpression : ~
UnaryExpression is
evaluated as follows:
Let expr be the result of evaluating UnaryExpression.
Return the result of applying bitwise complement to oldValue. The result is a signed 32-bit integer.
The
production UnaryExpression : !
UnaryExpression is
evaluated as follows:
Let expr be the result of evaluating UnaryExpression.
If oldValue is true, return false.
Return true.
Syntax
MultiplicativeExpression :
UnaryExpression
MultiplicativeExpression *
UnaryExpression
MultiplicativeExpression /
UnaryExpression
MultiplicativeExpression %
UnaryExpression
Semantics
The production MultiplicativeExpression : MultiplicativeExpression@ UnaryExpression, where @ stands for one of the operators in the above definitions, is evaluated as follows:
Let left be the result of evaluating MultiplicativeExpression.
Let leftValue be GetValue(left).
Let right be the result of evaluating UnaryExpression.
Let rightValue be GetValue(right).
Let leftNum be ToNumber(leftValue).
Let rightNum be ToNumber(rightValue).
Return the result of applying the specified operation (*, /, or %) to leftNum and rightNum. See the Notes below 11.5.1, 11.5.2, 11.5.3.
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 non-zero 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 non-zero 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 non-zero 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 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.
Syntax
AdditiveExpression :
MultiplicativeExpression
AdditiveExpression +
MultiplicativeExpression
AdditiveExpression -
MultiplicativeExpression
The addition operator either performs string concatenation or numeric addition.
The
production AdditiveExpression
: AdditiveExpression
+
MultiplicativeExpression
is evaluated as follows:
Let lref be the result of evaluating AdditiveExpression.
Let lval be GetValue(lref).
Let rref be the result of evaluating MultiplicativeExpression.
Let rval be GetValue(rref).
Let lprim be ToPrimitive(lval).
Let rprim be ToPrimitive(rval).
Return the result of applying the addition operation to ToNumber(lprim) and ToNumber(rprim). See the Note below 11.6.3.
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:
Let lref be the result of evaluating AdditiveExpression.
Let lval be GetValue(lref).
Let rref be the result of evaluating MultiplicativeExpression.
Let rval be GetValue(rref).
Let lnum be ToNumber(lval).
Let rnum be ToNumber(rval).
Return the result of applying the subtraction operation to lnum and rnum. See the note below 11.6.3.
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 zeros is −0. The sum of two positive zeros, or of two zeros 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)
.
Syntax
ShiftExpression :
AdditiveExpression
ShiftExpression <<
AdditiveExpression
ShiftExpression >>
AdditiveExpression
ShiftExpression >>>
AdditiveExpression
Performs 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:
Let lref be the result of evaluating ShiftExpression.
Let lval be GetValue(lref).
Let rref be the result of evaluating AdditiveExpression.
Let rval be GetValue(rref).
Let lnum be ToInt32(lval).
Let rnum be ToUint32(rval).
Let shiftCount be the result of masking out all but the least significant 5 bits of rnum, that is, compute rnum & 0x1F.
Return the result of left shifting lnum by shiftCount bits. The result is a signed 32-bit integer.
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:
Let lref be the result of evaluating ShiftExpression.
Let lval be GetValue(lref).
Let rref be the result of evaluating AdditiveExpression.
Let rval be GetValue(rref).
Let lnum be ToInt32(lval).
Let rnum be ToUint32(rval).
Let shiftCount be the result of masking out all but the least significant 5 bits of rnum, that is, compute rnum & 0x1F.
Return the result of performing a sign-extending right shift of lnum by shiftCount bits. The most significant bit is propagated. The result is a signed 32-bit integer.
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:
Let lref be the result of evaluating ShiftExpression.
Let lval be GetValue(lref).
Let rref be the result of evaluating AdditiveExpression.
Let rval be GetValue(rref).
Let lnum be ToUint32(lval).
Let rnum be ToUint32(rval).
Let shiftCount be the result of masking out all but the least significant 5 bits of rnum, that is, compute rnum & 0x1F.
Return the result of performing a zero-filling right shift of lnum by shiftCount bits. Vacated bits are filled with zero. The result is an unsigned 32-bit integer.
Syntax
RelationalExpression :
ShiftExpression
RelationalExpression <
ShiftExpression
RelationalExpression >
ShiftExpression
RelationalExpression <=
ShiftExpression
RelationalExpression >=
ShiftExpression
RelationalExpression instanceof
ShiftExpression
RelationalExpression in
ShiftExpression
RelationalExpressionNoIn :
ShiftExpression
RelationalExpressionNoIn <
ShiftExpression
RelationalExpressionNoIn >
ShiftExpression
RelationalExpressionNoIn <=
ShiftExpression
RelationalExpressionNoIn >=
ShiftExpression
RelationalExpressionNoIn instanceof
ShiftExpression
NOTE The
“NoIn” variants are needed to avoid confusing the in
operator in a relational expression with the in
operator in a for
statement.
Semantics
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:
Let lref be the result of evaluating RelationalExpression.
Let lval be GetValue(lref).
Let rref be the result of evaluating ShiftExpression.
Let rval be GetValue(rref).
Let r be the result of performing abstract relational comparison lval < rval. (see 11.8.5)
If r is undefined, return false. Otherwise, return r.
The
production RelationalExpression : RelationalExpression
>
ShiftExpression is
evaluated as follows:
Let lref be the result of evaluating RelationalExpression.
Let lval be GetValue(lref).
Let rref be the result of evaluating ShiftExpression.
Let rval be GetValue(rref).
Let r be the result of performing abstract relational comparison rval < lval with LeftFirst equal to false. (see 11.8.5).
If r is undefined, return false. Otherwise, return r.
The
production RelationalExpression : RelationalExpression
<=
ShiftExpression is
evaluated as follows:
Let lref be the result of evaluating RelationalExpression.
Let lval be GetValue(lref).
Let rref be the result of evaluating ShiftExpression.
Let rval be GetValue(rref).
Let r be the result of performing abstract relational comparison rval < lval with LeftFirst equal to false. (see 11.8.5).
If r is true or undefined, return false. Otherwise, return true.
The
production RelationalExpression : RelationalExpression
>=
ShiftExpression is
evaluated as follows:
Let lref be the result of evaluating RelationalExpression.
Let lval be GetValue(lref).
Let rref be the result of evaluating ShiftExpression.
Let rval be GetValue(rref).
Let r be the result of performing abstract relational comparison lval < rval. (see 11.8.5)
If r is true or undefined, return false. Otherwise, return true.
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:
If the LeftFirst flag is true, then
Let px be the result of calling ToPrimitive(x, hint Number).
Let py be the result of calling ToPrimitive(y, hint Number).
Else the order of evaluation needs to be reversed to preserve left to right evaluation
Let py be the result of calling ToPrimitive(y, hint Number).
Let px be the result of calling ToPrimitive(x, hint Number).
If it is not the case that both Type(px) is String and Type(py) is String, then
Let nx be the result of calling ToNumber(px). Because px and py are primitive values evaluation order is not important.
Let ny be the result of calling ToNumber(py).
If nx is NaN, return undefined.
If ny is NaN, return undefined.
If nx and ny are the same Number value, return false.
If nx is +0 and ny is −0, return false.
If nx is −0 and ny is +0, return false.
If nx is +∞, return false.
If ny is +∞, return true.
If ny is −∞, return false.
If nx is −∞, return true.
If the mathematical value of nx is less than the mathematical value of ny —note that these mathematical values are both finite and not both zero—return true. Otherwise, return false.
Else, both px and py are Strings
If py is a prefix of px, return false. (A String value p is a prefix of String value q if q can be the result of concatenating p and some other String r. Note that any String is a prefix of itself, because r may be the empty String.)
If px is a prefix of py, return true.
Let k be the smallest nonnegative integer such that the character at position k within px is different from the character at position k within py. (There must be such a k, for neither String is a prefix of the other.)
Let m be the integer that is the code unit value for the character at position k within px.
Let n be the integer that is the code unit value for the character at position k within py.
If m < n, return true. Otherwise, return false.
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:
Let lref be the result of evaluating RelationalExpression.
Let lval be GetValue(lref).
Let rref be the result of evaluating ShiftExpression.
Let rval be GetValue(rref).
If rval does not have a [[HasInstance]] internal method, throw a TypeError exception.
Return the result of calling the [[HasInstance]] internal method of rval with argument lval.
The
production RelationalExpression
: RelationalExpression
in
ShiftExpression
is evaluated as follows:
Let lref be the result of evaluating RelationalExpression.
Let lval be GetValue(lref).
Let rref be the result of evaluating ShiftExpression.
Let rval be GetValue(rref).
Return the result of calling the [[HasProperty]] internal method of rval with argument ToString(lval).
Syntax
EqualityExpression :
RelationalExpression
EqualityExpression ==
RelationalExpression
EqualityExpression !=
RelationalExpression
EqualityExpression ===
RelationalExpression
EqualityExpression !==
RelationalExpression
EqualityExpressionNoIn :
RelationalExpressionNoIn
EqualityExpressionNoIn ==
RelationalExpressionNoIn
EqualityExpressionNoIn !=
RelationalExpressionNoIn
EqualityExpressionNoIn ===
RelationalExpressionNoIn
EqualityExpressionNoIn !==
RelationalExpressionNoIn
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.
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:
Let lref be the result of evaluating EqualityExpression.
Let lval be GetValue(lref).
Let rref be the result of evaluating RelationalExpression.
Let rval be GetValue(rref).
Return the result of performing abstract equality comparison rval == lval. (see 11.9.3).
The
production EqualityExpression : EqualityExpression
!=
RelationalExpression
is evaluated as follows:
Let lref be the result of evaluating EqualityExpression.
Let lval be GetValue(lref).
Let rref be the result of evaluating RelationalExpression.
Let rval be GetValue(rref).
Let r be the result of performing abstract equality comparison rval == lval. (see 11.9.3).
If r is true, return false. Otherwise, return true.
The comparison x == y, where x and y are values, produces true or false. Such a comparison is performed as follows:
If Type(x) is the same as Type(y), then
If Type(x) is Undefined, return true.
If Type(x) is Null, return true.
If Type(x) is Number, then
If x is NaN, return false.
If y is NaN, return false.
If x is the same Number value as y, return true.
If x is +0 and y is −0, return true.
If x is −0 and y is +0, return true.
Return false.
If Type(x) is String, then return true if x and y are exactly the same sequence of characters (same length and same characters in corresponding positions). Otherwise, return false.
If Type(x) is Boolean, return true if x and y are both true or both false. Otherwise, return false.
Return true if x and y refer to the same object. Otherwise, return false.
If x is null and y is undefined, return true.
If x is undefined and y is null, return true.
If
Type(x) is Number and Type(y) is String,
return
the result of the comparison x == ToNumber(y).
If
Type(x) is String and Type(y) is Number,
return
the result of the comparison ToNumber(x) == y.
If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y.
If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).
If
Type(x) is either String or Number and Type(y) is
Object,
return the result of the comparison x ==
ToPrimitive(y).
If
Type(x) is Object and Type(y) is either String or
Number,
return the result of the comparison ToPrimitive(x)
== y.
Return false.
NOTE 1 Given the above definition of equality:
String
comparison can be forced by:
""
+ a == "" + b
.
Numeric
comparison can be forced by:
+a
== +b
.
Boolean
comparison can be forced by:
!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.
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:
Let lref be the result of evaluating EqualityExpression.
Let lval be GetValue(lref).
Let rref be the result of evaluating RelationalExpression.
Let rval be GetValue(rref).
Return the result of performing the strict equality comparison rval === lval. (See 11.9.6)
The
production EqualityExpression : EqualityExpression
!==
RelationalExpression
is evaluated as follows:
Let lref be the result of evaluating EqualityExpression.
Let lval be GetValue(lref).
Let rref be the result of evaluating RelationalExpression.
Let rval be GetValue(rref).
Let r be the result of performing strict equality comparison rval === lval. (See 11.9.6)
If r is true, return false. Otherwise, return true.
The comparison x === y, where x and y are values, produces true or false. Such a comparison is performed as follows:
If Type(x) is Undefined, return true.
If Type(x) is Null, return true.
If Type(x) is Number, then
If x is NaN, return false.
If y is NaN, return false.
If x is the same Number value as y, return true.
If x is +0 and y is −0, return true.
If x is −0 and y is +0, return true.
Return false.
If Type(x) is String, then return true if x and y are exactly the same sequence of characters (same length and same characters in corresponding positions); otherwise, return false.
If Type(x) is Boolean, return true if x and y are both true or both false; otherwise, return false.
Return true if x and y refer to the same object. Otherwise, return false.
NOTE This algorithm differs from the SameValue Algorithm (9.12) in its treatment of signed zeroes and NaNs.
Syntax
BitwiseANDExpression :
EqualityExpression
BitwiseANDExpression &
EqualityExpression
BitwiseANDExpressionNoIn :
EqualityExpressionNoIn
BitwiseANDExpressionNoIn &
EqualityExpressionNoIn
BitwiseXORExpression :
BitwiseANDExpression
BitwiseXORExpression ^
BitwiseANDExpression
BitwiseXORExpressionNoIn :
BitwiseANDExpressionNoIn
BitwiseXORExpressionNoIn ^
BitwiseANDExpressionNoIn
BitwiseORExpression :
BitwiseXORExpression
BitwiseORExpression |
BitwiseXORExpression
BitwiseORExpressionNoIn :
BitwiseXORExpressionNoIn
BitwiseORExpressionNoIn |
BitwiseXORExpressionNoIn
Semantics
The production A : A @ B, where @ is one of the bitwise operators in the productions above, is evaluated as follows:
Let lref be the result of evaluating A.
Let lval be GetValue(lref).
Let rref be the result of evaluating B.
Let rval be GetValue(rref).
Let lnum be ToInt32(lval).
Let rnum be ToInt32(rval).
Return the result of applying the bitwise operator @ to lnum and rnum. The result is a signed 32 bit integer.
Syntax
LogicalANDExpression :
BitwiseORExpression
LogicalANDExpression &&
BitwiseORExpression
LogicalANDExpressionNoIn :
BitwiseORExpressionNoIn
LogicalANDExpressionNoIn &&
BitwiseORExpressionNoIn
LogicalORExpression :
LogicalANDExpression
LogicalORExpression ||
LogicalANDExpression
LogicalORExpressionNoIn :
LogicalANDExpressionNoIn
LogicalORExpressionNoIn ||
LogicalANDExpressionNoIn
Semantics
The
production LogicalANDExpression
: LogicalANDExpression
&&
BitwiseORExpression
is evaluated as follows:
Let lref be the result of evaluating LogicalANDExpression.
Let lval be GetValue(lref).
If ToBoolean(lval) is false, return lval.
Let rref be the result of evaluating BitwiseORExpression.
Return GetValue(rref).
The
production LogicalORExpression
: LogicalORExpression
||
LogicalANDExpression
is evaluated as follows:
Let lref be the result of evaluating LogicalORExpression.
Let lval be GetValue(lref).
If ToBoolean(lval) is true, return lval.
Let rref be the result of evaluating LogicalANDExpression.
Return GetValue(rref).
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.
Syntax
ConditionalExpression :
LogicalORExpression
LogicalORExpression
?
AssignmentExpression :
AssignmentExpression
ConditionalExpressionNoIn :
LogicalORExpressionNoIn
LogicalORExpressionNoIn
?
AssignmentExpression :
AssignmentExpressionNoIn
Semantics
The
production ConditionalExpression
:
LogicalORExpression
?
AssignmentExpression
:
AssignmentExpression
is evaluated as follows:
Let lref be the result of evaluating LogicalORExpression.
If ToBoolean(GetValue(lref)) is true, then
Let trueRef be the result of evaluating the first AssignmentExpression.
Return GetValue(trueRef).
Else
Let falseRef be the result of evaluating the second AssignmentExpression.
Return GetValue(falseRef).
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.
Syntax
AssignmentExpression :
ConditionalExpression
LeftHandSideExpression
AssignmentOperator AssignmentExpression
AssignmentExpressionNoIn :
ConditionalExpressionNoIn
LeftHandSideExpression
AssignmentOperator AssignmentExpressionNoIn
AssignmentOperator : one of
|
|
|
|
|
|
|
|
|
|
|
|
Semantics
The AssignmentExpressionNoIn productions are evaluated in the same manner as the AssignmentExpression productions except that the contained ConditionalExpressionNoIn andAssignmentExpressionNoIn are evaluated instead of the contained ConditionalExpression and AssignmentExpression, respectively.
The
production AssignmentExpression
: LeftHandSideExpression
=
AssignmentExpression
is evaluated as follows:
Let lref be the result of evaluating LeftHandSideExpression.
Let rref be the result of evaluating AssignmentExpression.
Let rval be GetValue(rref).
Throw a SyntaxError exception if the following conditions are all true:
IsStrictReference(lref) is true
Type(GetBase(lref)) is Environment Record
GetReferencedName(lref)
is either "eval"
or "arguments"
Call PutValue(lref, rval).
Return rval.
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@ =
AssignmentExpression,
where @ represents one of the operators indicated above, is
evaluated as follows:
Let lref be the result of evaluating LeftHandSideExpression.
Let lval be GetValue(lref).
Let rref be the result of evaluating AssignmentExpression.
Let rval be GetValue(rref).
Let r be the result of applying operator @ to lval and rval.
Throw a SyntaxError exception if the following conditions are all true:
IsStrictReference(lref) is true
Type(GetBase(lref)) is Environment Record
GetReferencedName(lref)
is either "eval"
or "arguments"
Call PutValue(lref, r).
Return r.
NOTE See NOTE 11.13.1.
Syntax
Expression :
AssignmentExpression
Expression ,
AssignmentExpression
ExpressionNoIn :
AssignmentExpressionNoIn
ExpressionNoIn ,
AssignmentExpressionNoIn
Semantics
The
production Expression
: Expression
,
AssignmentExpression
is evaluated as follows:
Let lref be the result of evaluating Expression.
Call GetValue(lref).
Let rref be the result of evaluating AssignmentExpression.
Return GetValue(rref).
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.