Синтаксис
PrimaryExpression :
this
Identifier
Literal
ArrayLiteral
ObjectLiteral(
Expression )
Ключевое слово this
имеет значение ThisBinding текущего контекста исполнения.
Для вычисления значения Identifier Идентификатор выполняется Разрешение идентификатора, описание которого приводится в пункте 10.3.1. Результат вычисления значения Identifier всегда имеет значение типа Reference.
Вычисление значения Literal Литерал производится в соответствии с описанием в пункте 7.8.
Инициализатор массива представляет собой выражение, описывающее инициализацию объекта Array, записанное в виде литерала. Это список выражений в количестве ноль или более, каждое из которых представляет элемент массива, заключенный в квадратные скобки. Эти элементы не обязательно должны быть литералами – их значения вычисляются каждый раз при вычислении инициализатора массива.
Элементы массива могут быть пропущены в начале, в середине или в конце списка элементов. Если перед запятой в списке элементов отсутствует AssignmentExpression Выражение присваивания – т. е., запятая находится сразу в начале списка или непосредственно перед другой запятой – то пропущенный элемент массива увеличивает длину Array и индекс последующих элементов. Определение пропущенных элементов массива не производится. Элемент, пропущенный в конце массива, не увеличивает длину объекта Array.
Синтаксис
ArrayLiteral :
[
Elisionopt]
ElementList
[]
ElementList , Elisionopt
[]
ElementList :
ElisionoptAssignmentExpression
ElementList ,
ElisionoptAssignmentExpression
Elision :
,
Elision ,
Семантика
Для вычисления ArrayLiteral : [
Elisionopt]
выполняются следующие шаги:
Пусть array массив будет результатом создания нового объекта, как если бы этот объект был создан выражением new Array()
, где Array
является стандартным встроенным конструктором с этим именем.
Пусть pad будет результатом вычисления Elision Пропуск; если он отсутствует, использовать числовое значение ноль.
Вызвать внутренний метод [[Put]] для array с аргументами "
length
"
, pad и false.
Вернуть array.
Для вычисления ArrayLiteral : [
ElementList]
выполняются следующие шаги:
Вернуть результат вычисления ElementList Список элементов.
Для вычисления ArrayLiteral : [
ElementList ,
Elisionopt]
выполняются следующие шаги:
Пусть array будет результатом вычисления ElementList.
Пусть pad будет результатом вычисления Elision; если он отсутствует, использовать числовое значение ноль.
Пусть len будет результатом вызова внутреннего метода [[Get]] для array с аргументом "
length
"
.
Вызвать внутренний метод [[Put]] для array с аргументами "
length
"
, ToUint32(pad+len) и false.
Вернуть array.
Для вычисления ElementList : ElisionoptAssignmentExpression выполняются следующие шаги:
Пусть array будет результатом создания нового объекта, как если бы этот объект был создан выражением new Array()
, где Array
является стандартным встроенным конструктором с этим именем.
Пусть firstIndex будет результатом вычисления Elision; если он отсутствует, использовать числовое значение ноль.
Пусть initResult будет результатом вычисления AssignmentExpression.
Пусть initValue будет GetValue(initResult).
Вызвать внутренний метод [[DefineOwnProperty]] для array с аргументами ToString(firstIndex), Property Descriptor { [[Value]]: initValue, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true} и false.
Вернуть array.
Для вычисления ElementList : ElementList , ElisionoptAssignmentExpression выполняются следующие шаги:
Пусть array будет результатом вычисления ElementList.
Пусть pad будет результатом вычисления Elision; если он отсутствует, использовать числовое значение ноль.
Пусть initResult будет результатом вычисления AssignmentExpression.
Пусть initValue будет GetValue(initResult).
Пусть len будет результатом вызова внутреннего метода [[Get]] для array с аргументом "
length
"
.
Вызвать внутренний метод [[DefineOwnProperty]] для array с аргументами ToString(ToUint32((pad+len)) и Property Descriptor { [[Value]]: initValue, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true} и false.
Вернуть array.
Для вычисления Elision : , выполняются следующие шаги:
Вернуть числовое значение 1.
Для вычисления Elision : Elision , выполняются следующие шаги:
Пусть preceding будет результатом вычисления Elision.
Вернуть preceding+1.
ПРИМЕЧАНИЕ Использование внутреннего метода [[DefineOwnProperty]] позволяет обеспечить определение собственных свойства для этого массива, даже если стандартный встроенный объект-прототип Array был изменен таким образом, который препятствует созданию новых собственных свойств с использованием внутреннего метода [[Put]].
Инициализатор объекта представляет собой выражение, описывающее инициализацию Object, записанное в виде литерала. Это список из нуля или более пар из имен свойств и ассоциированных значений, заключенный в фигурные скобки. Эти значения не обязательно должны быть литералами – их вычисление производится каждый раз при вычислении инициализатора объекта.
Синтаксис
ObjectLiteral :
{ }
{
PropertyNameAndValueList}
PropertyNameAndValueList
{,
}
PropertyNameAndValueList :
PropertyAssignment
PropertyNameAndValueList,
PropertyAssignment
PropertyAssignment:
PropertyName :
AssignmentExpressionget
PropertyName ( )
{
FunctionBody }
set
PropertyName (
PropertySetParameterList ) {
FunctionBody }
PropertyName :
IdentifierName
StringLiteral
NumericLiteral
PropertySetParameterList:
Identifier
Семантика
Для вычисления ObjectLiteral : {
}
выполняются следующие шаги:
Вернуть новый объект, как если бы он был создан выражением new Object()
, где Object
является стандартным встроенным конструктором с этим именем.
Для вычисления ObjectLiteral : {
PropertyNameAndValueList
}
и
ObjectLiteral : {
PropertyNameAndValueList
,
}
выполняются следующие шаги:
Вернуть результат вычисления PropertyNameAndValueList Список имен свойств и значений.
Для вычисления PropertyNameAndValueList : PropertyAssignment выполняются следующие шаги:
Пусть obj будет результатом создания нового объекта, как если бы этот объект был создан выражением new Object()
, где Object
является стандартным встроенным конструктором с этим именем.
Пусть propId будет результатом вычисления PropertyAssignment Присваивания свойства.
Вызвать внутренний метод [[DefineOwnProperty]] для obj с аргументами propId.name, propId.descriptor и false.
Вернуть obj.
Для вычисления
PropertyNameAndValueList : PropertyNameAndValueList , PropertyAssignment
выполняются следующие шаги:
Пусть obj будет результатом вычисления PropertyNameAndValueList.
Пусть propId будет результатом вычисления PropertyAssignment.
Пусть previous будет результатом вызова внутреннего метода [[GetOwnProperty]] для obj с аргументом propId.name.
Если previous не является undefined, то сгенерировать исключение SyntaxError, если какое-либо из перечисленных ниже условий является истинным:
Это правило содержится в строгом коде, и при этом IsDataDescriptor(previous) – true и IsDataDescriptor(propId.descriptor) – true.
IsDataDescriptor(previous) равно true и IsAccessorDescriptor(propId.descriptor) равно true.
IsAccessorDescriptor(previous) равно true и IsDataDescriptor(propId.descriptor) равно true.
IsAccessorDescriptor(previous) равно true и IsAccessorDescriptor(propId.descriptor) равно true, и при этом либо и previous и propId.descriptor имеют поля [[Get]], либо и previous и propId.descriptor имеют поля [[Set]].
Вызвать внутренний метод [[DefineOwnProperty]] для obj с аргументами propId.name, propId.descriptor и false.
Вернуть obj.
Если при выполнении вышеперечисленных шагов будет сгенерировано исключение SyntaxError, то реализация должна интерпретировать эту ошибку как раннюю ошибку (Глава 16).
Для вычисления PropertyAssignment : PropertyName :
AssignmentExpression выполняются следующие шаги:
Пусть propName будет результатом вычисления PropertyName Имя свойства.
Пусть exprValue будет результатом вычисления AssignmentExpression.
Пусть propValue будет GetValue(exprValue).
Пусть desc будет Property Descriptor{[[Value]]: propValue, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}.
Вернуть Property Identifier (propName, desc).
Для вычисления PropertyAssignment : get
PropertyName ( ) {
FunctionBody}
выполняются следующие шаги:
Пусть propName будет результатом вычисления PropertyName.
Пусть closure будет результатом создания нового объекта Function в соответствии с описанием в пункте 13.2, с пустым списком параметров, при этом тело определено посредством FunctionBody. Передать LexicalEnvironment активного контекста исполнения в качестве области видимости Scope. Передать true в качестве флага Strict, если PropertyAssignment содержится в строгом коде, или если FunctionBody – строгий код.
Пусть desc будет Property Descriptor{[[Get]]: closure, [[Enumerable]]: true, [[Configurable]]: true}.
Вернуть Property Identifier (propName, desc).
Для вычисления PropertyAssignment : set
PropertyName (
PropertySetParameterList)
{
FunctionBody
}
выполняются следующие шаги:
Пусть propName будет результатом вычисления PropertyName.
Пусть closure будет результатом создания нового объекта Function в соответствии с описанием в пункте 13.2, с параметрами, заданными посредством PropertySetParameterList Список параметров набора свойств, при этом тело определено посредством FunctionBody. Передать LexicalEnvironment активного контекста исполнения в качестве области видимости Scope. Передать true в качестве флага Strict, если PropertyAssignment содержится в строгом коде, или если FunctionBody – строгий код.
Пусть desc будет Property Descriptor{[[Set]]: closure, [[Enumerable]]: true, [[Configurable]]: true}.
Вернуть Property Identifier (propName, desc).
Если Identifier "eval"
или Identifier "arguments"
встречается как Identifier в PropertySetParameterList для PropertyAssignment, который содержится в строгом коде, или если его FunctionBody – строгий код, то генерируется исключение SyntaxError.
Для вычисления PropertyName : IdentifierName выполняются следующие шаги:
Вернуть строковое значение, содержащее такую же последовательность символов, что и IdentifierName.
Для вычисления PropertyName : StringLiteral выполняются следующие шаги:
Вернуть строковое значение StringLiteral.
Для вычисления PropertyName : NumericLiteral выполняются следующие шаги:
Пусть nbr будет результатом формирования значения NumericLiteral.
Вернуть ToString(nbr).
Для вычисления PrimaryExpression : (
Expression )
выполняются следующие шаги:
Вернуть результат вычисления Expression Выражение. Он может иметь тип Reference.
ПРИМЕЧАНИЕ Этот алгоритм не применяет операцию GetValue к результату вычисления выражения. Основная причина заключается в том, чтобы к выражениям, заключенным в круглые скобки, могли применяться операторы delete
и typeof
.
Синтаксис
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
Доступ к свойствам осуществляется по имени. Для этого используется либо точечная запись (точечная нотация):
MemberExpression .
IdentifierName
CallExpression .
IdentifierName
либо скобочная запись:
MemberExpression [
Expression ]
CallExpression [
Expression ]
Для объяснения точечной записи используется следующее синтаксическое преобразование:
Запись
MemberExpression .
IdentifierName
по своему поведению тождественна записи
MemberExpression [
<identifier-name-string> ]
Аналогично, запись
CallExpression .
IdentifierName
по своему поведению тождественна записи
CallExpression [
<identifier-name-string> ]
где <identifier-name-string> строка имени идентификатора – строковый литерал, содержащий после обработки юникодных управляющих последовательностей такую же последовательность символов, что и IdentifierName.
Для вычисления MemberExpression : MemberExpression [
Expression ]
выполняются следующие шаги
Пусть baseReference будет результатом вычисления MemberExpression Выражение элемента.
Пусть baseValue будет GetValue(baseReference).
Пусть propertyNameReference Ссылка на имя свойства будет результатом вычисления Expression.
Пусть propertyNameValue Значение имени свойства будет GetValue(propertyNameReference).
Вызвать CheckObjectCoercible(baseValue).
Пусть propertyNameString Строка с именем свойства будет ToString(propertyNameValue).
Если преобразуемое синтаксическое правило содержится в коде в строгом режиме, то пусть strict будет true, иначе пусть strict будет false.
Вернуть значение типа Reference со значением базы baseValue, с именем ссылки propertyNameString и с флагом строгого режима strict.
Для вычисления CallExpression : CallExpression [
Expression ]
выполняются точно такие же шаги, за исключением того, что в шаге 1 вычисляется вложенное CallExpression.
Для вычисления NewExpression : new
NewExpression выполняются следующие шаги
Пусть ref будет результатом вычисления NewExpression.
Пусть constructor будет GetValue(ref).
Если Type(constructor) – не Object, сгенерировать исключение TypeError.
Если constructor не реализует внутренний метод [[Construct]], сгенерировать исключение TypeError.
Вернуть результат вызова внутреннего метода [[Construct]] для constructor, без передачи аргументов (то есть, с пустым списком аргументов).
Для вычисления MemberExpression : new
MemberExpression Arguments выполняются следующие шаги:
Пусть ref будет результатом вычисления MemberExpression.
Пусть constructor будет GetValue(ref).
Пусть argList будет результатом вычисления Arguments с созданием внутреннего списка значений аргументов (11.2.4).
Если Type(constructor) – не Object, сгенерировать исключение TypeError.
Если constructor не реализует внутренний метод [[Construct]], сгенерировать исключение TypeError.
Вернуть результат вызова внутреннего метода [[Construct]] для constructor, передавая в качестве значений аргументов argList.
Для вычисления CallExpression : MemberExpression Arguments выполняются следующие шаги:
Пусть ref будет результатом вычисления MemberExpression.
Пусть func будет GetValue(ref).
Пусть argList будет результатом вычисления Arguments с созданием внутреннего списка значений аргументов (см. 11.2.4).
Если Type(func) – не Object, сгенерировать исключение TypeError.
Если IsCallable(func) – false, сгенерировать исключение TypeError.
Если Type(ref) – Reference, то
Если IsPropertyReference(ref) – true, то
Пусть thisValue будет GetBase(ref).
Иначе, база для ref – Environment Record
Пусть thisValue будет результатои вызова конкретного метода ImplicitThisValue для GetBase(ref).
Иначе, Type(ref) не является Reference.
Пусть thisValue будет undefined.
Вернуть результат вызова внутреннего метода для func, передавая thisValue в качестве значения this, и передавая список argList в качестве значений аргумента.
Для вычисления CallExpression : CallExpression Arguments выполняются точно такие же шаги, за исключением того, что в шаге 1 вычисляется вложенное CallExpression.
ПРИМЕЧАНИЕ Возвращаемый результат не будет иметь тип Reference, если func представляет собой родной объект ECMAScript. Может ли вызываемый объект среды вернуть значение типа Reference, зависит от реализации. Если возвращается значение типа Reference, оно должно быть нестрогой ссылкой на свойство.
В результате вычисления списка аргументов получается список значений типа List (см. 8.8).
Для вычисления Arguments : ( )
выполняются следующие шаги:
Вернуть пустой список List.
Для вычисления Arguments : (
ArgumentList )
выполняются следующие шаги:
Вернуть результат вычисления ArgumentList Список аргументов.
Для вычисления ArgumentList : AssignmentExpression выполняются следующие шаги:
Пусть ref будет результатом вычисления AssignmentExpression.
Пусть arg будет GetValue(ref).
Вернуть список List с единственным элементом arg.
Для вычисления ArgumentList : ArgumentList
,
AssignmentExpression выполняются следующие шаги:
Пусть precedingArgs будет результатом вычисления ArgumentList.
Пусть ref будет результатом вычисления AssignmentExpression.
Пусть arg будет GetValue(ref).
Вернуть List, длина которого на одну единицу больше длины precedingArgs, элементы которого являются элементами precedingArgs по порядку, после которых находится arg, который является последним элементом нового списка.
Для вычисления MemberExpression : FunctionExpression выполняются следующие шаги:
Вернуть результат вычисления FunctionExpression Выражение функции.
Синтаксис
PostfixExpression :
LeftHandSideExpression
LeftHandSideExpression [no LineTerminator here]
++
LeftHandSideExpression [no LineTerminator here]
--
Для вычисления PostfixExpression : LeftHandSideExpression [no LineTerminator here]
++
выполняются следующие шаги:
Пусть lhs будет результатом вычисления LeftHandSideExpression Левостороннее выражение.
Сгенерировать исключение SyntaxError, если все следующие условия являются истинными:
IsStrictReference(lhs) равно true
Type(GetBase(lhs)) равно Environment Record
GetReferencedName(lhs) равно либо "eval"
, либо "arguments"
Пусть oldValue Старое значение будет ToNumber(GetValue(lhs)).
Пусть newValue Новое значение будет результатом прибавления значения 1
к значению oldValue, с применением таких же правил, что и для оператора +
(см. пункт. 11.6.3).
Вызвать PutValue(lhs, newValue).
Вернуть oldValue.
Для вычисления PostfixExpression : LeftHandSideExpression[no LineTerminator here]
--
выполняются следующие шаги:
Пусть lhs будет результатом вычисления LeftHandSideExpression Левостороннее выражение.
Сгенерировать исключение SyntaxError, если все следующие условия являются истинными:
IsStrictReference(lhs) равно true
Type(GetBase(lhs)) равно Environment Record
GetReferencedName(lhs) равно либо "eval"
, либо "arguments"
Пусть newValue будет результатом вычитания значения 1
из значения oldValue, с применением таких же правил, что и для оператора -
(см. пункт. 11.6.3).
Вызвать PutValue(lhs, newValue).
Вернуть oldValue.
Синтаксис
UnaryExpression :
PostfixExpression
UnaryExpression
deletevoid
UnaryExpressiontypeof
UnaryExpression
UnaryExpression
++--
UnaryExpression+
UnaryExpression-
UnaryExpression~
UnaryExpression!
UnaryExpression
Для вычисления UnaryExpression : delete
UnaryExpression выполняются следующие шаги:
Пусть ref будет результатом вычисления UnaryExpression Унарное выражение.
Если IsUnresolvableReference(ref), то
Если IsStrictReference(ref) – true, сгенерировать исключение SyntaxError.
Иначе, вернуть true.
Если IsPropertyReference(ref) – true, то
Вернуть результат вызова внутреннего метода [[Delete]] для абстрактной операции ToObject(GetBase(ref)), передавая в качестве аргументов GetReferencedName(ref) и IsStrictReference(ref).
Иначе, ref является ссылкой Reference на привязку к среде окружения Environment Record, поэтому
Если IsStrictReference(ref) – true, сгенерировать исключение SyntaxError.
Пусть bindings будет GetBase(ref).
Вернуть результат вызова конкретного метода DeleteBinding для bindings, передавая в качестве аргумента GetReferencedName(ref).
ПРИМЕЧАНИЕ Если оператор delete
встречается в рамках кода в строгом режиме, генерируется исключение SyntaxError, если его UnaryExpression является прямой ссылкой на переменную, аргумент функции или имя функции. Кроме того, исключение TypeError генерируется, если оператор delete
встречается в рамках кода в строгом режиме, и при этом свойство, подлежащее удалению, имеет атрибут { [[Configurable]]: false }.
Для вычисления UnaryExpression : void
UnaryExpression выполняются следующие шаги:
Пусть expr будет результатом вычисления UnaryExpression.
Вызвать GetValue(expr).
Вернуть undefined.
ПРИМЕЧАНИЕ Несмотря на то, что значение абстрактной операции GetValue не используется, её необходимо вызвать, поскольку она может иметь наблюдаемые побочные эффекты.
Для вычисления UnaryExpression : typeof
UnaryExpression выполняются следующие шаги:
Пусть val будет результатом вычисления UnaryExpression.
Если Type(val) – Reference, то
Если IsUnresolvableReference(val) – true, вернуть "undefined"
.
Пусть val будет GetValue(val).
Вернуть строку в зависимости от типа Type(val), в соответствии с Таблицей 20.
Тип для val |
Результат |
Undefined |
|
Null |
|
Boolean |
|
Number |
|
String |
|
Object (родной объект, не реализует [[Call]]) |
|
Object (родной объект или объект среды, реализует [[Call]]) |
|
Object (объект среды, не реализует [[Call]]) |
Зависит от реализации, но не может быть |
Для выполнения UnaryExpression : ++
UnaryExpression выполняются следующие шаги:
Пусть expr будет результатом вычисления UnaryExpression.
Сгенерировать исключение SyntaxError, если все следующие условия являются истинными:
IsStrictReference(expr) равно true
Type(GetBase(expr)) равно Environment Record
GetReferencedName(expr) равно либо "eval"
, либо "arguments"
Пусть newValue будет результатом прибавления значения 1
к значению oldValue, с применением таких же правил, что и для оператора +
(см. пункт. 11.6.3).
Вызвать PutValue(expr, newValue).
Вернуть newValue.
Для вычисления UnaryExpression : --
UnaryExpression выполняются следующие шаги:
Пусть expr будет результатом вычисления UnaryExpression.
Сгенерировать исключение SyntaxError, если все следующие условия являются истинными:
IsStrictReference(expr) равно true
Type(GetBase(expr)) равно Environment Record
GetReferencedName(expr) равно либо "eval"
, либо "arguments"
Пусть newValue будет результатом вычитания значения 1
из значения oldValue, с применением таких же правил, что и для оператора -
(см. пункт. 11.6.3).
Вызвать PutValue(expr, newValue).
Вернуть newValue.
Унарный оператор + преобразует свой операнд в тип Number.
Для вычисления UnaryExpression : +
UnaryExpression выполняются следующие шаги:
Унарный оператор -
преобразует свой операнд в тип Number, а затем выполняет операцию отрицания. Обратите внимание, что при отрицании +0 получается −0, а при отрицании −0 получается +0.
Для вычисления UnaryExpression : -
UnaryExpression выполняются следующие шаги:
Пусть expr будет результатом вычисления UnaryExpression.
Если oldValue равно NaN, вернуть NaN.
Вернуть результат отрицания oldValue; то есть, вычислить числовое значение такой же величины по модулю, но с противоположным знаком.
Для вычисления UnaryExpression : ~
UnaryExpression выполняются следующие шаги:
Пусть expr будет результатом вычисления UnaryExpression.
Вернуть результат применения к oldValue побитового дополнения. Результат является знаковым 32-битовым целым.
Для вычисления UnaryExpression : !
UnaryExpression выполняются следующие шаги:
Пусть expr будет результатом вычисления UnaryExpression.
Если oldValue равно true, вернуть false.
Вернуть true.
Синтаксис
MultiplicativeExpression :
UnaryExpression
MultiplicativeExpression *
UnaryExpression
MultiplicativeExpression /
UnaryExpression
MultiplicativeExpression %
UnaryExpression
Семантика
Для вычисления MultiplicativeExpression : MultiplicativeExpression@ UnaryExpression, где @ означает один из операторов в приведенных выше определениях, выполняются следующие шаги:
Пусть left будет результатом вычисления MultiplicativeExpression Мультипликативное выражение.
Пусть leftValue будет GetValue(left).
Пусть right будет результатом вычисления UnaryExpression.
Пусть rightValue будет GetValue(right).
Пусть leftNum будет ToNumber(leftValue).
Пусть rightNum будет ToNumber(rightValue).
Вернуть результат применения заданного оператора (*, /, or %) к leftNum или rightNum. См. примечания, приведенные далее в пунктах 11.5.1, 11.5.2, 11.5.3.
Оператор *
выполняет умножение, результатом которого является произведение его операндов. Умножение является коммутативным. Из-за конечной точности вычислений умножение в ECMAScript не всегда ассоциативно.
Результат произведения чисел с плавающей точкой обусловлен правилами стандарта IEEE 754 для двоичной арифметики двойной точности:
Если один из операндов – NaN, результат равен NaN.
Если оба операнда имеют одинаковые знаки, произведение является положительным. Если операнды имеют разные знаки, произведение является отрицательным.
При умножении бесконечности на ноль получается NaN.
При умножении бесконечности на бесконечность получается бесконечность. Знак, получаемый при этом, обусловлен правилом, описанным выше.
При умножении бесконечности на конечное ненулевое значение получается бесконечность со знаком. Знак, получаемый при этом, обусловлен правилом, описанным выше.
В остальных случаях, когда в операции умножения не участвуют ни бесконечность, ни NaN, произведение вычисляется и округляется до ближайшего представимого значения с использованием "режима округления до ближайшего значения" в соответствии со стандартом IEEE 754. Если значение слишком велико для представления, то результатом будет являться бесконечность с соответствующим знаком. Если значение слишком мало для представления, то результатом будет являться ноль с соответствующим знаком. Язык ECMAScript требует поддержки потери значимости в соответствии со стандартом IEEE 754.
Оператор /
выполняет деление, результатом которого является отношение его операндов. Левый операнд является делимым, а правый – делителем. Целочисленное деление в ECMAScript не производится. Операнды и результаты всех операций деления являются числами с плавающей точкой двойной точности. Результат деления обусловлен правилами арифметики в соответствии со стандартом IEEE 754:
Если один из операндов – NaN, результат равен NaN.
Если оба операнда имеют одинаковые знаки, результат деления является положительным. Если операнды имеют разные знаки, результат деления является отрицательным.
При делении бесконечности на бесконечность результат равен NaN.
При делении бесконечности на ноль результатом является бесконечность. Знак, получаемый при этом, обусловлен правилом, описанным выше.
При делении бесконечности на конечное ненулевое значение получается бесконечность со знаком. Знак, получаемый при этом, обусловлен правилом, описанным выше.
При делении конечного значения на бесконечность результат равен нулю. Знак, получаемый при этом, обусловлен правилом, описанным выше.
При делении нуля на ноль получается NaN. При делении нуля на любое другое конечное значение результат равен нулю, при этом получаемый знак обусловлен правилом, описанным выше.
При делении ненулевого конечного значения на ноль результат равен бесконечности со знаком. Знак, получаемый при этом, обусловлен правилом, описанным выше.
В остальных случаях, когда в операции умножения не участвуют ни бесконечность, ни ноль, ни NaN, отношение вычисляется и округляется до ближайшего представимого значения с использованием "режима округления до ближайшего значения" в соответствии со стандартом IEEE 754. Если значение слишком велико для представления, произойдёт переполнение, и результатом будет являться бесконечность с соответствующим знаком. Если значение слишком мало для представления, произойдёт потеря значимости, и результатом будет являться ноль с соответствующим знаком. Язык ECMAScript требует поддержки потери значимости в соответствии со стандартом IEEE 754.
Оператор %
генерирует остаток от деления своих операндов. Левый операнд является делимым, а правый – делителем.
ПРИМЕЧАНИЕ В языках C и C++ оператор остатка принимает только целые операнды, а в языке ECMAScript он принимает и операнды с плавающей точкой.
Результат операции получения остатка для чисел с плавающей точкой, полученный посредством оператора %
, отличается от операции "остатка" в соответствии с IEEE 754. В стандарте IEEE 754 операция "остатка" вычисляет остаток от деления с округлением, а не от деления с усечением – таким образом, её поведение не аналогично поведению обычного оператора получения целого остатка. В отличие от IEEE 754, язык ECMAScript определяет поведение остатка %
от операций с плавающей точкой аналогичным поведению оператора получения целого остатка в языке Java. Это можно сравнить с функцией fmod в библиотеке С.
Результат операции получения остатка для чисел с плавающей точкой в языке ECMAScript обусловлен правилами арифметики в соответствии со стандартом IEEE:
Если один из операндов – NaN, результат равен NaN.
Знак результата равен знаку делимого.
Если делимое равно бесконечности или делитель равен нулю, или если выполняются оба эти условия, то результат равен NaN.
Если делимое является конечным числом, а делитель равен бесконечности, результат равен делимому.
Если делимое равно нулю, а делитель является конечным числом, результат равен делимому.
В остальных случаях, когда в операции не участвуют ни бесконечность, ни ноль, ни NaN, остаток r для чисел с плавающей запятой для делимого n и делителя d определяется математическим отношением r = n − (d * q), где q – целое число, которое является отрицательным, только если n/d отрицательно, и положительным, только если n/d положительно, и чьё значение по модулю является наибольшим значением, не превышающим значения по модулю истинного математического отношения чисел n и d. Значение r вычисляется и округляется до ближайшего представимого значения с использованием "режима округления до ближайшего значения" в соответствии со стандартом IEEE 754.
Синтаксис
AdditiveExpression :
MultiplicativeExpression
AdditiveExpression +
MultiplicativeExpression
AdditiveExpression -
MultiplicativeExpression
Оператор сложения производит либо конкатенацию строк, либо суммирование чисел.
Для вычисления AdditiveExpression : AdditiveExpression +
MultiplicativeExpression выполняются следующие шаги:
Пусть lref будет результатом вычисления AdditiveExpression.
Пусть lval будет GetValue(lref).
Пусть rref будет результатом вычисления MultiplicativeExpression.
Пусть rval будет GetValue(rref).
Пусть lprim будет ToPrimitive(lval).
Пусть rprim будет ToPrimitive(rval).
Вернуть результат применения операции сложения к ToNumber(lprim) и ToNumber(rprim). См. примечание ниже в пункте 11.6.3.
ПРИМЕЧАНИЕ 1 При вызовах абстрактной операции ToPrimitive в шаге 5 и 6 подсказка не предоставляется. Все родные объекты ECMAScript (кроме объектов Date) обрабатывают отсутствие подсказки, как если бы была передана подсказка Number, а объекты Date обрабатывают отсутствие подсказки, как если бы была дана подсказка String. Объекты среды могут обрабатывать отсутствие подсказки как-либо иначе.
ПРИМЕЧАНИЕ 2 Шаг 7 отличается от шага 3 сравнительного алгоритма операторов отношения (11.8.5) использованием операции логического "или" вместо операции логического "и".
Для вычисления AdditiveExpression : AdditiveExpression -
MultiplicativeExpression выполняются следующие шаги:
Пусть lref будет результатом вычисления AdditiveExpression.
Пусть lval будет GetValue(lref).
Пусть rref будет результатом вычисления MultiplicativeExpression.
Пусть rval будет GetValue(rref).
Пусть lnum будет ToNumber(lval).
Пусть rnum будет ToNumber(rval).
Вернуть результат применения операции вычитания к lnum и rnum. См. примечание ниже в пункте 11.6.3.
В применении к двум числовым операндам, оператор +
выполняет сложение и генерирует сумму этих операндов, а оператор -
выполняет вычитание и генерирует разницу двух числовых операндов.
Сложение – коммутативная операция, однако она не всегда является ассоциативной.
Результат сложения обусловлен правилами стандарта IEEE 754 для двоичной арифметики двойной точности:
Если один из операндов – NaN, результат равен NaN.
Сумма двух бесконечностей с противоположными знаками равна NaN.
Сумма двух бесконечностей с одним и тем же знаком равна бесконечности с тем же знаком.
Сумма бесконечности и конечного значения равна бесконечному операнду.
Сумма двух отрицательных нулей равна −0. Сумма двух положительных нулей или двух нулей с противоположными знаками равна +0.
Сумма нуля и ненулевого конечного значения равна ненулевому операнду.
Сумма двух ненулевых конечных значений одинаковой величины с противоположными знаками равна +0.
В остальных случаях, когда в операции умножения не участвуют ни бесконечность, ни ноль, ни NaN, и при этом операнды имеют разные величины или одинаковый знак, сумма вычисляется и округляется до ближайшего представимого значения с использованием "режима округления до ближайшего значения" в соответствии со стандартом IEEE 754. Если значение слишком велико для представления, произойдёт переполнение, и результатом будет являться бесконечность с соответствующим знаком. Язык ECMAScript требует поддержки потери значимости в соответствии со стандартом IEEE 754.
В применении к двум числовым операндам, оператор -
выполняет вычитание и генерирует разницу его операндов. Левый операнд – уменьшаемое, а правый – вычитаемое. Для числовых операндов a и b, результат вычитания a–
b всегда равен результату сложения a +(–
b)
.
Синтаксис
ShiftExpression :
AdditiveExpression
ShiftExpression <<
AdditiveExpression
ShiftExpression >>
AdditiveExpression
ShiftExpression >>>
AdditiveExpression
Производит над левым операндом операцию побитового сдвига влево, сдвигая его на количество бит, указанное в правом операнде.
Для вычисления ShiftExpression : ShiftExpression <<
AdditiveExpression выполняются следующие шаги:
Пусть lref будет результатом вычисления ShiftExpression Выражение сдвига.
Пусть lval будет GetValue(lref).
Пусть rref будет результатом вычисления AdditiveExpression Аддитивное выражение.
Пусть rval будет GetValue(rref).
Пусть lnum будет ToInt32(lval).
Пусть rnum будет ToUint32(rval).
Пусть shiftCount будет результатом маскировки всех битов rnum, кроме пяти младших, то есть – вычислить rnum & 0x1F.
Вернуть результат сдвига lnum влево на shiftCount битов. Результат является знаковым 32-битовым целым.
Производит над левым операндом операцию побитового сдвига вправо со вставкой знака, сдвигая его на количество бит, указанное в правом операнде.
Для вычисления ShiftExpression : ShiftExpression >>
AdditiveExpression выполняются следующие шаги:
Пусть lref будет результатом вычисления ShiftExpression.
Пусть lval будет GetValue(lref).
Пусть rref будет результатом вычисления AdditiveExpression.
Пусть rval будет GetValue(rref).
Пусть lnum будет ToInt32(lval).
Пусть rnum будет ToUint32(rval).
Пусть shiftCount будет результатом маскировки всех битов rnum, кроме пяти младших, то есть – вычислить rnum & 0x1F.
Вернуть результат сдвига вправо с добавлением знака для lnum на shiftCount битов, при этом в освободившиеся места копируется старший бит. Результат является знаковым 32-битовым целым.
Производит над левым операндом операцию побитового сдвига вправо с нулевой вставкой, сдвигая его на количество бит, указанное в правом операнде.
Для вычисления ShiftExpression : ShiftExpression >>>
AdditiveExpression выполняются следующие шаги:
Пусть lref будет результатом вычисления ShiftExpression.
Пусть lval будет GetValue(lref).
Пусть rref будет результатом вычисления AdditiveExpression.
Пусть rval будет GetValue(rref).
Пусть lnum будет ToUint32(lval).
Пусть rnum будет ToUint32(rval).
Пусть shiftCount будет результатом маскировки всех битов rnum, кроме пяти младших, то есть – вычислить rnum & 0x1F.
Вернуть результат сдвига вправо с нулевой вставкой для lnum на shiftCount битов, при этом в освободившиеся места вставляется ноль. Результат является беззнаковым 32-битовым целым.
Синтаксис
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
ПРИМЕЧАНИЕ Варианты с "NoIn" необходимы для того, чтобы не перепутать оператор in
в выражении отношения с оператором in
в инструкции for
.
Семантика
Результат вычисления оператора отношения всегда имеет тип Boolean. Он показывает, находится ли отношение, описываемое этим оператором, в пределах его двоих операндов.
Для вычисления RelationalExpressionNoIn Выражение отношения без in выполнятся точно такие же шаги, что и для вычисления RelationalExpression Выражение отношения, за исключением того, что вместо вложенного RelationalExpression вычисляется вложенное RelationalExpressionNoIn.
Для вычисления RelationalExpression : RelationalExpression <
ShiftExpression выполняются следующие шаги:
Пусть lref будет результатом вычисления RelationalExpression.
Пусть lval будет GetValue(lref).
Пусть rref будет результатом вычисления ShiftExpression.
Пусть rval будет GetValue(rref).
Пусть r будет результатом абстрактного сравнения отношения lval < rval – см. пункт 11.8.5.
Если r – undefined, вернуть false. Иначе вернуть r.
Для вычисления RelationalExpression : RelationalExpression >
ShiftExpression выполняются следующие шаги:
Пусть lref будет результатом вычисления RelationalExpression.
Пусть lval будет GetValue(lref).
Пусть rref будет результатом вычисления ShiftExpression.
Пусть rval будет GetValue(rref).
Пусть r будет результатом абстрактного сравнения отношения rval < lval, при этом LeftFirst равно false – см. пункт 11.8.5.
Если r – undefined, вернуть false. Иначе вернуть r.
Для вычисления RelationalExpression : RelationalExpression <=
ShiftExpression выполняются следующие шаги:
Пусть lref будет результатом вычисления RelationalExpression.
Пусть lval будет GetValue(lref).
Пусть rref будет результатом вычисления ShiftExpression.
Пусть rval будет GetValue(rref).
Пусть r будет результатом абстрактного сравнения отношения rval < lval, при этом LeftFirst равно false – см. пункт 11.8.5.
Если r – true или undefined, вернуть false. Иначе вернуть true.
Для вычисления RelationalExpression : RelationalExpression >=
ShiftExpression выполняются следующие шаги:
Пусть lref будет результатом вычисления RelationalExpression.
Пусть lval будет GetValue(lref).
Пусть rref будет результатом вычисления ShiftExpression.
Пусть rval будет GetValue(rref).
Пусть r будет результатом абстрактного сравнения отношения lval < rval – см. пункт 11.8.5.
Если r – true или undefined, вернуть false. Иначе вернуть true.
Результатом сравнения x < y, где x и y – значения, является true, false или undefined (последнее означает, что, по крайней мере, один операнд равен NaN). Кроме x и y этот алгоритм принимает в качестве параметра булев флаг LeftFirst Сначала левый. Этот флаг контролирует порядок, в соответствии с которым над x и y производятся операции с потенциально видимыми побочными эффектами. Этот флаг необходим потому, что в языке ECMAScript задан порядок вычисления выражений слева направо. Значение флага LeftFirst по умолчанию – true, которое означает, что параметр x соответствует выражению, которое находится слева от соответствующего выражения параметра y. Если значение флага LeftFirst – false, то параметры меняются местами, и сначала необходимо произвести операции над y, а потом – над x. Это сравнение производится следующим образом:
Если флаг LeftFirst – true, то
Пусть px будет результатом вызова абстрактной операции ToPrimitive(x, подсказка Number).
Пусть py будет результатом вызова абстрактной операции ToPrimitive(y, подсказка Number).
Иначе, необходимо поменять местами порядок вычисления, чтобы сохранить вычисление слева направо.
Пусть py будет результатом вызова абстрактной операции ToPrimitive(y, подсказка Number).
Пусть px будет результатом вызова абстрактной операции ToPrimitive(x, подсказка Number).
Если неверно, что и Type(px) – String, и Type(py) – String, то
Пусть nx будет результатом вызова ToNumber(px). Порядок вычисления неважен, поскольку px и py – примитивные значения.
Пусть ny будет результатом вызова ToNumber(py).
Если nx – NaN, вернуть undefined.
Если ny – NaN, вернуть undefined.
Если nx и ny имеют одинаковое числовое значение, вернуть false.
Если nx равно +0 и ny равно −0, вернуть false.
Если nx равно −0 и ny равно +0, вернуть false.
Если nx равно +∞, вернуть false.
Если ny равно +∞, вернуть true.
Если ny равно −∞, вернуть false.
Если nx равно −∞, вернуть true.
Если математическое значение nx меньше, чем математическое значение ny (обратите внимание, что оба эти математические значения конечны и не являются оба равными нулю), вернуть true. В противном случае вернуть false.
Иначе, и px и py – строки.
Если py – префикс для px, вернуть false. (Строковое значение p является префиксом строкового значения q, если q может быть результатом конкатенации p и какой-либо другой строки r. Обратите внимание, что любая строка является префиксом самой себя, поскольку r может быть пустой строкой).
Если px – префикс для py, вернуть true.
Пусть k будет таким наименьшим неотрицательным целым числом, чтобы символ в позиции k в пределах px отличался от символа в позиции k в пределах py. (Такое k должно иметь место, поскольку ни одна строка не является префиксом другой.)
Пусть m будет целым числом, которое имеет значение кодовой единицы для символа в позиции k в пределах px.
Пусть n будет целым числом, которое имеет значение кодовой единицы для символа в позиции k в пределах py.
Если m < n, вернуть true. В противном случае вернуть false.
ПРИМЕЧАНИЕ 1 Шаг 3 отличается от шага 7 в алгоритме для оператора сложения +
(11.6.1) тем, что в нем используется союз "и", а не "или".
ПРИМЕЧАНИЕ 2 Для сравнения строк используется простое лексикографическое упорядочение последовательностей значений кодовых единиц. Данный алгоритм не пытается использовать более сложные семантически ориентированные определения равенства символов или строк и порядка сортировки, определение которых содержится в спецификации Юникода. Поэтому строковые значения, которые являются канонически равными в соответствии со стандартом Юникод, могут в результате проверки оказаться неравными. В действительности, данный алгоритм предполагает, что обе строки находятся уже в нормализованном виде. Кроме того, обратите внимание, что для строк, содержащих дополнительные символы, лексикографическое упорядочение последовательностей значений кодовых единиц в кодировке UTF-16 отличается от лексикографического упорядочения последовательностей значений кодовых точек.
Для вычисления RelationalExpression: RelationalExpression instanceof
ShiftExpression выполняются следующие шаги:
Пусть lref будет результатом вычисления RelationalExpression.
Пусть lval будет GetValue(lref).
Пусть rref будет результатом вычисления ShiftExpression.
Пусть rval будет GetValue(rref).
Если Type(rval) – не Object, сгенерировать исключение TypeError.
Если rval не имеет внутреннего метода [[HasInstance]], сгенерировать исключение TypeError.
Вернуть результат вызова внутреннего метода [[HasInstance]] для rval с аргументом lval.
Для вычисления RelationalExpression : RelationalExpression in
ShiftExpression выполняются следующие шаги:
Пусть lref будет результатом вычисления RelationalExpression.
Пусть lval будет GetValue(lref).
Пусть rref будет результатом вычисления ShiftExpression.
Пусть rval будет GetValue(rref).
Если Type(rval) – не Object, сгенерировать исключение TypeError.
Вернуть результат вызова внутреннего метода [[HasProperty]] для rval с аргументом ToString(lval).
Синтаксис
EqualityExpression :
RelationalExpression
EqualityExpression ==
RelationalExpression
EqualityExpression !=
RelationalExpression
EqualityExpression ===
RelationalExpression
EqualityExpression !==
RelationalExpression
EqualityExpressionNoIn :
RelationalExpressionNoIn
EqualityExpressionNoIn ==
RelationalExpressionNoIn
EqualityExpressionNoIn !=
RelationalExpressionNoIn
EqualityExpressionNoIn ===
RelationalExpressionNoIn
EqualityExpressionNoIn !==
RelationalExpressionNoIn
Семантика
Результат вычисления оператора равенства всегда имеет тип Boolean. Он показывает, находится ли отношение, описываемое этим оператором, в пределах его двоих операндов.
Для вычисления EqualityExpressionNoIn Выражение равенства без in выполняются точно такие же шаги, что и для вычисления EqualityExpression Выражение равенства , за исключением того, что вместо вложенных EqualityExpression и RelationalExpression вычисляются вложенные EqualityExpressionNoIn и RelationalExpressionNoIn, соответственно.
Для вычисления EqualityExpression : EqualityExpression ==
RelationalExpression выполняются следующие шаги:
Пусть lref будет результатом вычисления EqualityExpression.
Пусть lval будет GetValue(lref).
Пусть rref будет результатом вычисления RelationalExpression.
Пусть rval будет GetValue(rref).
Вернуть результат сравнения абстрактного равенства rval == lval (см. пункт 11.9.3).
Для вычисления EqualityExpression : EqualityExpression !=
RelationalExpression выполняются следующие шаги:
Пусть lref будет результатом вычисления EqualityExpression.
Пусть lval будет GetValue(lref).
Пусть rref будет результатом вычисления RelationalExpression.
Пусть rval будет GetValue(rref).
Пусть r будет результатом сравнения абстрактного равенства rval == lval – см. пункт 11.9.3).
Если r – true, вернуть false. Иначе вернуть true.
Сравнение x == y, где x и y являются значениями, возвращает true или false. Это сравнение производится следующим образом:
Если Type(x) такой же, что и Type(y), то
Если Type(x) – Undefined, вернуть true.
Если Type(x) – Null, вернуть true.
Если Type(x) – Number, то
Если x – NaN, вернуть false.
Если y – NaN, вернуть false.
Если x имеет такое же числовое значение, что и y, вернуть true.
Если x равно +0 и y равно −0, вернуть true.
Если x равно −0 и y равно +0, вернуть true.
Вернуть false.
Если Type(x) – String, то вернуть true, если x и y имеют абсолютно одинаковую последовательность символов (одинаковой длины и с одинаковыми символами в соответствующих позициях). В противном случае вернуть false.
Если Type(x) – Boolean, вернуть true, если x и y оба являются или true, или false. В противном случае вернуть false.
Вернуть true, если x и y относятся к одному и тому же объекту. В противном случае вернуть false.
Если x равно null и y – undefined, вернуть true.
Если x – undefined и y – null, вернуть true.
Если Type(x) – Number и Type(y) – String,
вернуть результат сравнения x == ToNumber(y).
Если Type(x) – String и Type(y) – Number,
вернуть результат сравнения ToNumber(x) == y.
Если Type(x) – Boolean, вернуть результат сравнения ToNumber(x) == y.
Если Type(y) – Boolean, вернуть результат сравнения x == ToNumber(y).
Если Type(x) – либо String, либо Number, и Type(y) – Object,
вернуть результат сравнения x == ToPrimitive(y).
Если Type(x) – Object и Type(y) –либо String, либо Number,
вернуть результат сравнения ToPrimitive(x) == y.
Вернуть false.
ПРИМЕЧАНИЕ Принимая во внимание вышеуказанное определение равенства:
Принудительно сделать сравнение строковым можно следующим образом: "" + a == "" + b
.
Принудительно сделать сравнение числовым можно следующим образом: +a == +b
.
Принудительно сделать сравнение булевым можно следующим образом: !a == !b
.
ПРИМЕЧАНИЕ 2 Операторы равенства поддерживают следующие инварианты:
A
!=
B
эквивалентно !(A
==
B)
.
A
==
B
эквивалентно B
==
A
, за исключением порядка вычисления значения A
и B
.
ПРИМЕЧАНИЕ 3 Оператор равенства не всегда транзитивен. Например: допустим, существуют два различные объекта типа String с одинаковым строковым значением. Каждый объект типа String будет считаться равным строковому значению посредством оператора ==
, но при этом эти два объекта String не будут равны друг другу.
ПРИМЕЧАНИЕ 4 Для сравнения строк используется простая проверка равенства последовательностей значений кодовых единиц. Данный алгоритм не пытается использовать более сложные семантически ориентированные определения равенства символов или строк и порядка сортировки, определение которых содержится в спецификации Юникода. Поэтому строковые значения, которые являются канонически равными в соответствии со стандартом Юникод, могут в результате проверки оказаться неравными. В действительности, данный алгоритм предполагает, что обе строки находятся уже в нормализованном виде.
Для вычисления EqualityExpression : EqualityExpression ===
RelationalExpression выполняются следующие шаги:
Пусть lref будет результатом вычисления EqualityExpression.
Пусть lval будет GetValue(lref).
Пусть rref будет результатом вычисления RelationalExpression.
Пусть rval будет GetValue(rref).
Вернуть результат ставнения строгого равенства rval === lval – см. пункт 11.9.6).
Для вычисления EqualityExpression : EqualityExpression !==
RelationalExpression выполняются следующие шаги:
Пусть lref будет результатом вычисления EqualityExpression.
Пусть lval будет GetValue(lref).
Пусть rref будет результатом вычисления RelationalExpression.
Пусть rval будет GetValue(rref).
Пусть r будет результатом сравнения строгого равенства rval == lval – см. пункт 11.9.6).
Если r – true, вернуть false. Иначе вернуть true.
Сравнение x ===y, где x и y являются значениями, возвращает true или false. Это сравнение производится следующим образом:
Если Type(x) – Undefined, вернуть true.
Если Type(x) – Null, вернуть true.
Если Type(x) – Number, то
Если x – NaN, вернуть false.
Если y – NaN, вернуть false.
Если x имеет такое же числовое значение, что и y, вернуть true.
Если x равно +0 и y равно −0, вернуть true.
Если x равно −0 и y равно +0, вернуть true.
Вернуть false.
Если Тип(x) – String, то вернуть true, если x и y имеют абсолютно одинаковую последовательность символов (одинаковой длины и с одинаковыми символами в соответствующих позициях), иначе вернуть false.
Если Type(x) – Boolean, вернуть true, если x и y оба являются или true, или false; иначе вернуть false.
Вернуть true, если x и y относятся к одному и тому же объекту. В противном случае вернуть false.
ПРИМЕЧАНИЕ Этот алгоритм отличается от алгоритма SameValue (9.12) в вопросе обработки нулей со знаком и значений "не-число" (NaN).
Синтаксис
BitwiseANDExpression :
EqualityExpression
BitwiseANDExpression &
EqualityExpression
BitwiseANDExpressionNoIn :
EqualityExpressionNoIn
BitwiseANDExpressionNoIn &
EqualityExpressionNoIn
BitwiseXORExpression :
BitwiseANDExpression
BitwiseXORExpression ^
BitwiseANDExpression
BitwiseXORExpressionNoIn :
BitwiseANDExpressionNoIn
BitwiseXORExpressionNoIn ^
BitwiseANDExpressionNoIn
BitwiseORExpression :
BitwiseXORExpression
BitwiseORExpression |
BitwiseXORExpression
BitwiseORExpressionNoIn :
BitwiseXORExpressionNoIn
BitwiseORExpressionNoIn |
BitwiseXORExpressionNoIn
Семантика
Для вычисления A : A @ B, где @ – один из побитовых операторов в перечисленных выше правилах, выполняются следующие шаги:
Пусть lref будет результатом вычисления A.
Пусть lval будет GetValue(lref).
Пусть rref будет результатом вычисления B.
Пусть rval будет GetValue(rref).
Пусть lnum будет ToInt32(lval).
Пусть rnum будет ToInt32(rval).
Вернуть результат применения побитового оператора @ к lnum и rnum. Результат является знаковым 32-битовым целым.
Синтаксис
LogicalANDExpression :
BitwiseORExpression
LogicalANDExpression &&
BitwiseORExpression
LogicalANDExpressionNoIn :
BitwiseORExpressionNoIn
LogicalANDExpressionNoIn &&
BitwiseORExpressionNoIn
LogicalORExpression :
LogicalANDExpression
LogicalORExpression ||
LogicalANDExpression
LogicalORExpressionNoIn :
LogicalANDExpressionNoIn
LogicalORExpressionNoIn ||
LogicalANDExpressionNoIn
Семантика
Для вычисления LogicalANDExpression : LogicalANDExpression &&
BitwiseORExpression выполняются следующие шаги:
Пусть lref будет результатом вычисления LogicalANDExpression Выражение логического И.
Пусть lval будет GetValue(lref).
Если ToBoolean(lval) равно false, вернуть lval.
Пусть rref будет результатом вычисления BitwiseORExpression Выражение побитового ИЛИ.
Вернуть GetValue(rref).
Для вычисления LogicalORExpression : LogicalORExpression ||
LogicalANDExpression выполняются следующие шаги:
Пусть lref будет результатом вычисления LogicalORExpression Выражение логического ИЛИ.
Пусть lval будет GetValue(lref).
Если ToBoolean(lval) равно true, вернуть lval.
Пусть rref будет результатом вычисления LogicalANDExpression.
Вернуть GetValue(rref).
Для вычисления LogicalANDExpressionNoIn Выражение логического И без in и LogicalORExpressionNoIn Выражение логического ИЛИ без in выполняются точно такие же шаги, что и для вычисления LogicalANDExpression и LogicalORExpression, за исключением того, что вместо вложенных LogicalANDExpression, BitwiseORExpression и LogicalORExpression вычисляются вложенные LogicalANDExpressionNoIn, BitwiseORExpressionNoIn Выражение побитового ИЛИ без in и LogicalORExpressionNoIn, соответственно.
ПРИМЕЧАНИЕ Значение, возвращаемое оператором &&
или ||
, не обязательно имеет тип Boolean, при этом оно всегда будет являться значением одного из двух выражений-операндов.
Синтаксис
ConditionalExpression :
LogicalORExpression
LogicalORExpression ?
AssignmentExpression :
AssignmentExpression
ConditionalExpressionNoIn :
LogicalORExpressionNoIn
LogicalORExpressionNoIn ?
AssignmentExpression :
AssignmentExpressionNoIn
Семантика
Для вычисления UnaryExpression : LogicalORExpression ?
AssignmentExpression :
AssignmentExpression выполняются следующие шаги:
Пусть lref будет результатом вычисления LogicalORExpression.
Если ToBoolean(GetValue(lref)) равно true, то
Пусть trueRef будет результатом вычисления первого AssignmentExpression.
Вернуть GetValue(trueRef).
Иначе
Пусть falseRef будет результатом вычисления второго AssignmentExpression.
Вернуть GetValue(falseRef).
Для вычисления ConditionalExpressionNoIn Условное выражение без in выполняются точно такие же шаги, что и для вычисления ConditionalExpression Условное выражение, за исключением того, что вместо вложенных LogicalORExpression, первого AssignmentExpression и второго AssignmentExpression вычисляются вложенные LogicalORExpressionNoIn, AssignmentExpression и AssignmentExpressionNoIn, соответственно.
ПРИМЕЧАНИЕ Грамматика условных выражений в языке ECMAScript отличается от грамматики условных выражений в языках C и Java, которые оба позволяют, чтобы второе подвыражение являлось выражением (Expression), но ограничивают третье выражение, позволяя ему быть лишь условным выражением (Conditional Expression). Это отличие в языке ECMAScript объясняется тем, что ECMAScript позволяет, чтобы выражение присваивания могло управляться любым ответвлением условного выражения; это также позволяет избежать использования запятой в качестве центрального выражения, которое является довольно бесполезным и может ввести в заблуждение.
Синтаксис
AssignmentExpression :
ConditionalExpression
LeftHandSideExpression AssignmentOperator AssignmentExpression
AssignmentExpressionNoIn :
ConditionalExpressionNoIn
LeftHandSideExpression AssignmentOperator AssignmentExpressionNoIn
AssignmentOperator : один из
|
|
|
|
|
|
|
|
|
|
|
|
Семантика
Для вычисления AssignmentExpressionNoIn Выражение присваивания без in выполняются точно такие же шаги, что и для вычисления AssignmentExpression Выражение присваивания, за исключением того, что вместо вложенных ConditionalExpression и AssignmentExpression вычисляются вложенные ConditionalExpressionNoIn и AssignmentExpressionNoIn, соответственно.
Для вычисления AssignmentExpression : LeftHandSideExpression =
AssignmentExpression выполняются следующие шаги:
Пусть lref будет результатом вычисления LeftHandSideExpression Левосторонее выражение.
Пусть rref будет результатом вычисления AssignmentExpression.
Пусть rval будет GetValue(rref).
Сгенерировать исключение SyntaxError, если все следующие условия являются истинными:
IsStrictReference(lref) равно true
Type(GetBase(lref)) равно Environment Record
GetReferencedName(lref) равно либо "eval"
, либо "arguments"
Вызвать PutValue(lref, rval).
Вернуть rval.
ПРИМЕЧАНИЕ Если присваивание имеет место в рамках кода в строгом режиме, его LeftHandSide Левая сторона при вычислении не должна производить неразрешённую ссылку. Если это происходит, то при таком присваивании генерируется исключение ReferenceError. Кроме того, LeftHandSide не может быть ссылкой на свойство данных со значением атрибута {[[Writable]]:false}, на свойство аксессоров со значением атрибута {[[Set]]:undefined}, а также на несуществующее свойство объекта, у которого внутреннее свойство [[Extensible]] имеет значение false. В этих случаях генерируется исключение TypeError.
Для вычисления AssignmentExpression : LeftHandSideExpression@ =
AssignmentExpression, где @ означает один из перечисленных выше операторов, выполняются следующие шаги:
Пусть lref будет результатом вычисления LeftHandSideExpression.
Пусть lval будет GetValue(lref).
Пусть rref будет результатом вычисления AssignmentExpression.
Пусть rval будет GetValue(rref).
Пусть r будет результатом применения оператора @ к lval и rval.
Сгенерировать исключение SyntaxError, если все следующие условия являются истинными:
IsStrictReference(lref) равно true
Type(GetBase(lref)) равно Environment Record
GetReferencedName(lref) равно либо "eval"
, либо "arguments"
Вызвать PutValue(lref, r).
Вернуть r.
ПРИМЕЧАНИЕ См. Примечание к пункту 11.13.1.
Синтаксис
Expression :
AssignmentExpression
Expression ,
AssignmentExpression
ExpressionNoIn :
AssignmentExpressionNoIn
ExpressionNoIn ,
AssignmentExpressionNoIn
Семантика
Для вычисления UnaryExpression : Expression ,
AssignmentExpression выполняются следующие шаги:
Пусть lref будет результатом вычисления Expression.
Вызвать GetValue(lref).
Пусть rref будет результатом вычисления AssignmentExpression.
Вернуть GetValue(rref).
Для вычисления ExpressionNoIn выполняются точно такие же шаги, что и для вычисления Expression, за исключением того, что вместо вложенных Expression и AssignmentExpression вычисляются вложенные ExpressionNoIn и AssignmentExpressionNoIn, соответственно.
ПРИМЕЧАНИЕ Несмотря на то, что значение абстрактной операции GetValue не используется, её необходимо вызвать, поскольку она может иметь наблюдаемые побочные эффекты.