Синтаксис
Значением ключевого слова this является значение this текущего контекста исполнения.
Значение Идентификатора вычисляется согласно правилам действия областей видимости, указанным в разделе 10.1.4. Результатом получения значения Идентификатора всегда является значение типа Reference.
Значение Литерала вычисляется согласно описанию в разделе 7.8.
Инициализатором массива называется выражение, описывающее инициализацию объекта Array, записанное в форме литерала. Оно представляет собой заключённый в квадратные скобки список из нуля или более выражений, каждое из которых является элементом массива. Элементы не обязательно должны быть литералами. Их значения вычисляются каждый раз, когда вычисляется значение инициализатора.
Элементы массива могут быть опущены в начале, середине или конце списка элементов. Если в любом месте списка элементов встречается запятая, перед которой не присутствует ВыражениеПрисваивания (т. е. запятая в начале списка или сразу после другой запятой), пропущенный элемент массива увеличивает длину объекта Array и индексы последующих элементов. Опущенные элементы массива являются неопределёнными.
Синтаксис
Семантика
Значение нетерминала ЛитералМассива : [ Пропускопц ] вычисляется по следующей схеме:
1. Создать новый массив, как он был бы создан выражением new Array().
2. Вычислить значение Пропуска (если он отсутствует, использовать численное значение ноль).
3. Вызвать метод [[Put]] Результата(1) с аргументами "length" и Результат(2).
4. Вернуть Результат(1).
Значение нетерминала ЛитералМассива : [ СписокЭлементов ] вычисляется по следующей схеме:
1. Вычислить значение СпискаЭлементов.
2. Вернуть Результат(1).
Значение нетерминала ЛитералМассива : [ СписокЭлементов , Пропускопц ] вычисляется по следующей схеме:
1. Вычислить значение СпискаЭлементов.
2. Вычислить значение Пропуска (если он отсутствует, использовать численное значение ноль).
3. Вызвать метод [[Get]] Результата(1) с аргументом "length".
4. Вызвать метод [[Put]] Результата(1) с аргументами "length" и (Результат(2) + Результат(3)).
5. Вернуть Результат(1).
Значение нетерминала ЛитералМассива : Пропускопц ВыражениеПрисваивания вычисляется по следующей схеме:
1. Создать новый массив, как он был бы создан выражением new Array().
2. Вычислить значение Пропуска (если он отсутствует, использовать численное значение ноль).
3. Вычислить значение ВыраженияПрисваивания.
4. Вызвать ПолучитьЗначение(Результат(3)).
5. Вызвать метод [[Put]] Результата(1) с аргументами Результат(2) и Результат(4).
6. Вернуть Результат(1)
Значение нетерминала ЛитералМассива : СписокЭлементов , Пропускопц ВыражениеПрисваивания вычисляется по следующей схеме:
1. Вычислить значение СпискаЭлементов.
2. Вычислить значение Пропуска (если он отсутствует, использовать численное значение ноль).
3. Вычислить значение ВыраженияПрисваивания.
4. Вызвать ПолучитьЗначение(Результат(3)).
5. Вызвать метод [[Get]] Результата(1) с аргументом "length".
6. Вызвать метод [[Put]] Результата(1) с аргументами (Результат(2)+ Результат(5)) и Результат(4).
7. Вернуть Результат(1)
Значение нетерминала Пропуск : , вычисляется по следующей схеме:
1. Вернуть численное значение 1.
Значение нетерминала Пропуск : Пропуск , вычисляется по следующей схеме:
1. Вычислить Пропуск.
2. Вернуть (Результат(1)+ 1).
Инициализатором объекта называется выражение, описывающее инициализацию сущности типа Object, записанное в форме литерала. Оно представляет собой заключённый в фигурные скобки список из нуля или более названий свойств и соответствующих им значений. Значения не обязательно должны быть литералами - они вычисляются каждый раз, когда вычисляется значение инициализатора.
Синтаксис
Семантика
Значение нетерминала ЛитералОбъекта : {} вычисляется по следующей схеме:
1. Создать новый объект, как он был бы создан выражением new Object().
2. Вернуть Результат(1).
Значение нетерминала ЛитералОбъекта : { СписокИмёнСвойствИЗначений } вычисляется по следующей схеме:
1. Вычислить значение СпискаИмёнСвойствИЗначений.
2. Вернуть Результат(1).
Значение нетерминала СписокИмёнСвойствИЗначений : ИмяСвойства : ВыражениеПрисваивания вычисляется по следующей схеме:
1. Создать новый объект, как он был бы создан выражением new Object().
2. Вычислить значение ИмениСвойства.
3. Вычислить значение ВыраженияПрисваивания.
4. Вызвать ПолучитьЗначение(Результат(3)).
5. Вызвать метод [[Put]] Результата(1) с аргументами Результат(2) и Результат(4).
6. Вернуть Результат(1).
Значение нетерминала СписокИмёнСвойствИЗначений : СписокИмёнСвойствИЗначений , ИмяСвойства : ВыражениеПрисваивания вычисляется по следующей схеме:
1. Вычислить значение СпискаИмёнСвойствИЗначений.
2. Вычислить значение ИмениСвойства.
3. Вычислить значение ВыраженияПрисваивания.
4. Вызвать ПолучитьЗначение(Результат(3)).
5. Вызвать метод [[Put]] Результата(1) с аргументами Результат(2) и Результат(4).
6. Вернуть Результат(1).
Значение нетерминала ИмяСвойства : Идентификатор вычисляется по следующей схеме:
1. Сформировать строку, содержащую такую же последовательность символов, что и Идентификатор.
2. Вернуть Результат(1).
Значение нетерминала ИмяСвойства : СтроковойЛитерал вычисляется по следующей схеме:
1. Вернуть значение СтроковогоЛитерала.
Значение нетерминала ИмяСвойства : ЧисловойЛитерал вычисляется по следующей схеме:
1. Построить значение ЧисленногоЛитерала.
2. Вернуть ToString(Результат(1)).
Значение нетерминала ПервичноеВыражение : ( Выражение ) вычисляется по следующей схеме:
1. Вычислить значение Выражения. Результат может иметь тип Reference.
2. Вернуть Результат(1).
ЗАМЕЧАНИЕ
Вышеприведённый алгоритм не применяет ПолучитьЗначение к Результату(1). Основной причиной для такого поведения является обеспечение возможности применения таких операторов как delete и typeof к выражениям в скобках.
Синтаксис
Доступ к свойствам осуществляется по их имени с использованием либо точечной нотации:
ВыражениеЭлемента . Идентификатор
ВыражениеCall . Идентификатор
либо скобочной нотации:
ВыражениеЭлемента [ Выражение ]
ВыражениеCall [ Выражение ]
Объяснить суть точечной нотации можно следующим синтаксическим преобразованием:
ВыражениеЭлемента . Идентификатор
идентично по своему поведению
ВыражениеЭлемента [ <строка-идентификатора> ]
и аналогично
ВыражениеCall . Идентификатор
идентично по своему поведению ВыражениюCall [ <строка-идентификатора> ]
где <строка-идентификатора> - строковой литерал, содержащий ту же последовательность символов, что и Идентификатор.
Значение нетерминала ВыражениеЭлемента : ВыражениеЭлемента [ Выражение ] вычисляется по следующей схеме:
1. Вычислить значение ВыраженияЭлемента.
2. Вызвать ПолучитьЗначение(Результат(1)).
3. Вычислить значение Выражения.
4. Вызвать ПолучитьЗначение(Результат(3)).
5. Вызвать ToObject(Результат(2)).
6. Вызвать ToString(Результат(4)).
7. Вернуть значение типа Reference, базовым объектом которого является Результат(5), а именем свойства - Результат(6).
Значение нетерминала ВыражениеCall : ВыражениеCall [ Выражение ] вычисляется совершенно аналогично за исключением того, что на шаге 1 вычисляется значение вложенного ВыраженияCall.
Значение нетерминала ВыражениеNew : new ВыражениеNew вычисляется по следующей схеме:
1. Вычислить значение ВыраженияNew.
2. Вызвать ПолучитьЗначение(Результат(1)).
3. Если Тип(Результата(2)) не Object, бросить исключение TypeError.
4. Если для Результата(2) не реализован внутренний метод [[Construct]], бросить исключение TypeError.
5. Вызвать метод [[Construct]] для Результата(2), не передав ему аргументов (т.е. передав пустой список аргументов).
6. Вернуть Результат(5).
Значение нетерминала ВыражениеЭлемента : new ВыражениеЭлемента Аргументы вычисляется по следующей схеме:
1. Вычислить значение ВыраженияЭлемента.
2. Вызвать ПолучитьЗначение(Результат(1)).
3. Вычислить значение Аргументов, создав внутренний список значений аргументов (см. раздел 11.2.4).
4. Если Тип(Результата(2)) не Object, бросить исключение TypeError.
5. Если для Результата(2) не реализован внутренний метод [[Construct]], бросить исключение TypeError.
6. Вызвать метод [[Construct]] у Результата(2), передав список Result(3) в качестве значений аргументов.
7. Вернуть Результат(6).
Значение нетерминала ВыражениеCall : ВыражениеЭлемента Аргументы вычисляется по следующей схеме:
1. Вычислить значение ВыраженияЭлемента.
2. Вычислить значение Аргументов, создав внутренний список значений аргументов (см. раздел 11.2.4).
3. Вызвать ПолучитьЗначение(Результат(1)).
4. Если Тип(Результата(3)) не Object - бросить исключение TypeError.
5. Если для Результата(3) не реализован внутренний метод [[Call]] - бросить исключение TypeError.
6. Если Тип(Результата(1)) - Reference, Результат(6) равен ПолучитьБазу(Результат(1)). Иначе Результат(6) равен null.
7. Если Результат(6) является объектом активации, Результат(7) равен null. Иначе Результат(7) совпадает с Результатом(6).
8. Вызвать метод [[Call]] у Результата(3), передав Result(7) в качестве значения this и список Result(2) в качестве значений аргументов.
9. Вернуть Результат(8).
Значение нетерминала ВыражениеCall : ВыражениеCall Аргументы вычисляется совершенно аналогично за исключением того, что на шаге 1 вычисляется значение вложенного ВыраженияCall.
ЗАМЕЧАНИЕ
Результат(8) никогда не будет иметь тип Reference, если Результат(3) является встроенным объектом ECMAScript. Может ли объект среды вернуть значение типа Reference - зависит от конкретной реализации.
В результате вычисления значения списка аргументов создаётся внутренний список значений (см. раздел 8.8).
Значение нетерминала Аргументы : () вычисляется по следующей схеме:
1. Вернуть пустой список значений.
Значение нетерминала Аргументы : ( СписокАргументов ) вычисляется по следующей схеме:
1. Вычислить значение СпискаАргументов.
2. Вернуть Результат(1).
Значение нетерминала СписокАргументов : ВыражениеПрисваивания вычисляется по следующей схеме:
1. Вычислить значение ВыраженияПрисваивания.
2. Вызвать ПолучитьЗначение(Результат(1)).
3. Вернуть внутренний список, состоящий из единственного элемента - Результата(2).
Значение нетерминала СписокАргументов : СписокАргументов , ВыражениеПрисваивания вычисляется по следующей схеме:
1. Вычислить значение СпискаАргументов.
2. Вычислить значение ВыраженияПрисваивания.
3. Вызвать ПолучитьЗначение(Результат(2)).
4. Вернуть внутренний список, длина которого на единицу больше, чем у Результата(1), и элементы которого являются расположенными в том же порядке элементами Результата(1), за которыми следует Результат(3) в качестве последнего элемента нового списка.
Значение нетерминала ВыражениеЭлемента : ВыражениеФункции вычисляется по следующей схеме:
1. Вычислить значение ВыраженияФункции.
2. Вернуть Результат(1).
Синтаксис
Значение нетерминала ПостфиксноеВыражение : ЛевостороннееВыражение [здесь нет КонцаСтроки] ++ вычисляется по следующей схеме:
1. Вычислить значение ЛевостороннегоВыражения.
2. Вызвать ПолучитьЗначение(Результат(1)).
3. Вызвать ToNumber(Результат(2)).
4. Прибавить значение 1 к Результату(3) согласно тем же правилам, что и для оператора + (см. раздел 11.6.3).
5. Вызвать ЗаписатьЗначение(Результат(1), Результат(4)).
6. Вернуть Результат(3).
Значение нетерминала ПостфиксноеВыражение : ЛевостороннееВыражение [здесь нет КонцаСтроки] -- вычисляется по следующей схеме:
1. Вычислить значение ЛевостороннегоВыражения.
2. Вызвать ПолучитьЗначение(Результат(1)).
3. Вызвать ToNumber(Результат(2)).
4. Вычесть значение 1 из Результата(3) согласно тем же правилам, что и для оператора - (см. раздел 11.6.3).
5. Вызвать ЗаписатьЗначение(Результат(1), Результат(4)).
6. Вернуть Результат(3).
Синтаксис
Значение нетерминала УнарноеВыражение : delete УнарноеВыражение вычисляется по следующей схеме:
1. Вычислить значение УнарногоВыражения.
2. Если Тип(Результата(1)) не Reference - вернуть true.
3. Вызвать ПолучитьБазу(Результат(1)).
4. Вызвать ПолучитьИмяСвойства(Результат(1)).
5. Вызвать метод [[Delete]] для Результата(3), передав Результат(4) в качестве имени свойства, подлежащего удалению.
6. Вернуть Результат(5).
Значение нетерминала УнарноеВыражение : void УнарноеВыражение вычисляется по следующей схеме:
1. Вычислить значение УнарногоВыражения.
2. Вызвать ПолучитьЗначение(Результат(1)).
3. Вернуть undefined.
Значение нетерминала УнарноеВыражение : typeof УнарноеВыражение вычисляется по следующей схеме:
1. Вычислить значение УнарногоВыражения.
2. Если Тип(Результата(1)) не Reference - переход на шаг 4.
3. Если ПолучитьБазу(Результата(1)) равно null - вернуть "undefined".
4. Вызвать ПолучитьЗначение(Результат(1)).
5. Вернуть строку, определяемую Типом(Результата(4)) согласно следующей таблице:
| Тип | Результат |
|---|---|
| Undefined | "undefined" |
| Null | "object" |
| Boolean | "boolean" |
| Number | "number" |
| String | "string" |
| Object (встроенный и не имеет реализации [[Call]]) | "object" |
| Object (встроенный и имеет реализацию [[Call]]) | "function" |
| Object (среды выполнения) | зависит от конкретной реализации |
Значение нетерминала УнарноеВыражение : ++ УнарноеВыражение вычисляется по следующей схеме:
1. Вычислить значение УнарногоВыражения.
2. Вызвать ПолучитьЗначение(Результат(1)).
3. Вызвать ToNumber(Результат(2)).
4. Прибавить значение 1 к Результату(3) согласно тем же правилам, что и для оператора + (см. раздел 11.6.3).
5. Вызвать ЗаписатьЗначение(Результат(1), Результат(4)).
6. Вернуть Результат(4).
Значение нетерминала УнарноеВыражение : -- УнарноеВыражение вычисляется по следующей схеме:
1. Вычислить значение УнарногоВыражения.
2. Вызвать ПолучитьЗначение(Результат(1)).
3. Вызвать ToNumber(Результат(2)).
4. Вычесть значение 1 из Результата(3), используя те же правила, что и для оператора - (см. раздел 11.6.3).
5. Вызвать ЗаписатьЗначение(Результат(1), Результат(4)).
6. Вернуть Результат(4).
Унарный оператор + преобразует свой операнд к типу Number.
Значение нетерминала УнарноеВыражение : + УнарноеВыражение вычисляется по следующей схеме:
1. Вычислить значение УнарногоВыражения.
2. Вызвать ПолучитьЗначение(Результат(1)).
3. Вызвать ToNumber(Результат(2)).
4. Вернуть Результат(3).
Унарный оператор - преобразует свой операнд к типу Number и меняет его знак на противоположный. Заметим, что смена знака для +0 даёт -0, а смена знака для -0 даёт +0.
Значение нетерминала УнарноеВыражение : - УнарноеВыражение вычисляется по следующей схеме:
1. Вычислить значение УнарногоВыражения.
2. Вызвать ПолучитьЗначение(Результат(1)).
3. Вызвать ToNumber(Результат(2)).
4. Если Результат(3) равен NaN - вернуть NaN.
5. Изменить знак(3), т.е. вычислить число с таким же значением модуля, но с противоположным знаком.
6. Вернуть Результат(5).
Значение нетерминала УнарноеВыражение : ~ УнарноеВыражение вычисляется по следующей схеме:
1. Вычислить значение УнарногоВыражения.
2. Вызвать ПолучитьЗначение(Результат(1)).
3. Вызвать ToInt32(Результат(2)).
4. Вычислить побитовое дополнение к Результату(3). Результатом является знаковое 32-битное целое число.
5. Вернуть Результат(4).
Значение нетерминала УнарноеВыражение : ! УнарноеВыражение вычисляется по следующей схеме:
1. Вычислить значение УнарногоВыражения.
2. Вызвать ПолучитьЗначение(Результат(1)).
3. Вызвать ToBoolean(Результат(2)).
4. Если Результат(3) равен true - вернуть false.
5. Вернуть true.
Синтаксис
Семантика
Значение нетерминала МультипликативноеВыражение : МультипликативноеВыражение @ УнарноеВыражение, где @ заменяет один из операторов в вышеперечисленных определениях, вычисляется по следующей схеме:
1. Вычислить значение МультипликативногоВыражения.
2. Вызвать ПолучитьЗначение(Результат(1)).
3. Вычислить значение УнарногоВыражения.
4. Вызвать ПолучитьЗначение(Результата(3)).
5. Вызвать ToNumber(Результат(2)).
6. Вызвать ToNumber(Результат(4)).
7.Применить указанную операцию (*, /, или %) к Результату(5) и Результату(6). См. замечания ниже (разделы 11.5.1, 11.5.2, 11.5.3).
8.Вернуть Результат(7).
Оператор * производит умножение, генерируя произведение своих операндов. Умножение коммутативно. Умножение в ECMAScript не всегда ассоциативно вследствие конечной точности вычислений.
Результат произведения чисел с плавающей точкой соответствует правилам арифметики двойной точности стандарта IEEE 754:
Оператор / производит деление, генерируя частное своих операндов. Левый операнд является делимым, а правый - делителем. ECMAScript не производит целочисленного деления. Операнды и результат деления являются вещественными числами с плавающей точкой двойной точности. Результат деления определён спецификацией арифметики стандарта IEEE 754:
Оператор % возвращает остаток от подразумеваемого деления своих операндов. Левый операнд является делимым, а правый - делителем.
ЗАМЕЧАНИЕ
В языках C и C++ оператор получения остатка принимает только целые операнды. Но в языке ECMAScript он также принимает числа с плавающей точкой.
Результат операции получения остатка для чисел с плавающей точкой при помощи оператора % отличается от операции "остаток", определённой в IEEE 754. Операция "остаток" в IEEE 754 вычисляет остаток от округляющего, а не отбрасывающего деления, и, таким образом, её поведение не является аналогичным обычной операции взятия целочисленного остатка. Вместо этого язык ECMAScript определяет операцию % для чисел с плавающей точкой, которая по поведению аналогична операции взятия целочисленного остатка в языке Java. Также она является аналогичной функции fmod из стандартной библиотеки C.
Результат получения остатка для чисел с плавающей запятой в ECMAScript определяется правилами арифметики IEEE:
Оператор сложения производит либо конкатенацию строк, либо численное сложение.
Значение нетерминала АддитивноеВыражение : АддитивноеВыражение + МультипликативноеВыражение вычисляется по следующей схеме:
1. Вычислить значение АддитивногоВыражения.
2. Вызвать ПолучитьЗначение(Результата(1)).
3. Вычислить значение МультипликативногоВыражения.
4. Вызвать ПолучитьЗначение(Результата(3)).
5. Вызвать ToPrimitive(Результат(2)).
6.Вызвать ToPrimitive(Результат(4)).
7.Если Тип(Результат(5)) равен String или Тип(Результат(6)) равен String - переход на шаг 12. (Заметим, что этот шаг отличается от шага 3 в алгоритме сравнения для операторов отношения тем, что в нём используется или вместо и.)
8. Вызвать ToNumber(Результат(5)).
9. Вызвать ToNumber(Результат(6)).
10. Применить операцию сложения к Результату(8) и Результату(9). См. замечание ниже (раздел 11.6.3).
11. Вернуть Результат(10).
12. Вызвать ToString(Результат(5)).
13. Вызвать ToString(Результат(6)).
14. Конкатенировать Результат(12) с результатом Результатом(13).
15. Вернуть Результат(14).
ЗАМЕЧАНИЕ
Для вызовов ToPrimitive на шагах 5 и 6 не указывается параметр-подсказка. Все встроенные объекты ECMAScript кроме Date обрабатывают отсутствие подсказки так, как будто была передана подсказка Number. Объекты Date обрабатывают отсутствие подсказки так, как будто была передана подсказка String. Объекты среды могут обрабатывать отсутствие подсказки каким-либо другим образом.
Значение нетерминала АддитивноеВыражение : АддитивноеВыражение - МультипликативноеВыражение вычисляется по следующей схеме:
1. Вычислить значение АддитивногоВыражения.
2. Вызвать ПолучитьЗначение(Результата(1)).
3. Вычислить значение МультипликативногоВыражения.
4. Вызвать ПолучитьЗначение(Результата(3)).
5. Вызвать ToNumber(Результат(2)).
6. Вызвать ToNumber(Результат(4)).
7. Применить операцию вычитания к Результату(5) и Результату(6). См. замечание ниже (раздел 11.6.3).
8.Вернуть Результат(7).
Оператор +, применённый к двум операндам численного типа, производит сложение и возвращает сумму операндов. Оператор - производит вычитание и возвращает разность своих численных операндов.
Сложение - коммутативная операция, но не всегда ассоциативная.
Результат сложения чисел с плавающей точкой соответствует правилам арифметики двойной точности стандарта IEEE 754:
Оператор + применённый к двум операндам численного типа, производит вычитание и возвращает разность операндов. Левый операнд является уменьшаемым, правый - вычитаемым. Для численных операндов a и b значения выражений a- b и a+(- b) всегда равны.
Синтаксис
Производит операцию побитового сдвига влево на левом операнде, сдвигая его на количество бит, указанное в правом операнде.
Значение нетерминала ВыражениеСдвига : ВыражениеСдвига << АддитивноеВыражение вычисляется по следующей схеме:
1. Вычислить значение ВыраженияСдвига.
2. Вызвать ПолучитьЗначение(Результата(1)).
3. Вычислить значение АддитивногоВыражения.
4. Вызвать ПолучитьЗначение(Результат(3)).
5. Вызвать ToInt32(Результат(2)).
6. Вызвать ToUint32(Результат(4)).
7.Отбросить все биты Результата(6) кроме 5 младших, т.е. вычислить Результат(6) & 0x1F.
8. Сдвинуть Результат(5) влево на (7) бит. Результатом является знаковое 32-битное целое число.
9. Вернуть Результат(8).
Производит операцию побитового сдвига вправо с дополнением знака на левом операнде, сдвигая его на количество бит, указанное в правом операнде.
Значение нетерминала ВыражениеСдвига : ВыражениеСдвига >> АддитивноеВыражение вычисляется по следующей схеме:
1. Вычислить значение ВыраженияСдвига.
2. Вызвать ПолучитьЗначение(Результата(1)).
3. Вычислить значение АддитивногоВыражения.
4. Вызвать ПолучитьЗначение(Результат(3)).
5. Вызвать ToInt32(Результат(2)).
6. Вызвать ToUint32(Результат(4)).
7.Отбросить все биты Результата(6) кроме 5 младших, т.е. вычислить Результат(6) & 0x1F.
8. Сдвинуть Результат(5) вправо на (7) бит с дополнением знака. Значение старшего бита копируется в "освободившиеся" старшие разряды. Результатом является знаковое 32-битное целое число.
9. Вернуть Результат(8).
Производит операцию побитового сдвига вправо с дополнением нулём на левом операнде, сдвигая его на количество бит, указанное в правом операнде.
Значение нетерминала ВыражениеСдвига : ВыражениеСдвига >>> АддитивноеВыражение вычисляется по следующей схеме:
1. Вычислить значение ВыраженияСдвига.
2. Вызвать ПолучитьЗначение(Результата(1)).
3. Вычислить значение АддитивногоВыражения.
4. Вызвать ПолучитьЗначение(Результат(3)).
5. Вызвать ToUint32(Результат(2)).
6. Вызвать ToUint32(Результат(4)).
7.Отбросить все биты Результата(6) кроме 5 младших, т.е. вычислить Результат(6) & 0x1F.
8. Сдвинуть Результат(5) вправо на (7) бит с расширением знака. "Освободившиеся" старшие разряды заполняются нулями. Результатом является беззнаковое 32-битное целое число.
9. Вернуть Результат(8).
Синтаксис
ЗАМЕЧАНИЕ
Варианты 'БезIn' нужны для избежания путаницы между оператором in в выражениях отношения и оператором in в инструкции for.
Семантика
Результат вычисления значения оператора отношения всегда имеет тип Boolean и обозначает, существует ли определяемое оператором отношение между двумя операндами
Значения нетерминалов ВыражениеОтношенияБезIn вычисляются по той же схеме, что и для нетерминалов ВыражениеОтношения за исключением того, что значение вложенного ВыраженияОтношенияБезIn вычисляется вместо вложенного ВыраженияОтношения.
Значение нетерминала ВыражениеОтношения : ВыражениеОтношения < ВыражениеСдвига вычисляется по следующей схеме:
1. Вычислить значение ВыраженияОтношения.
2. Вызвать ПолучитьЗначение(Результата(1)).
3. Вычислить значение ВыраженияСдвига.
4. Вызвать ПолучитьЗначение(Результата(3)).
5. Произвести сравнение Результат(2) < Результат(4) (см. раздел 11.8.5).
6. Если Результат(5) равен undefined - вернуть false. Иначе вернуть Результат(5).
Значение нетерминала ВыражениеОтношения : ВыражениеОтношения > ВыражениеСдвига вычисляется по следующей схеме:
1. Вычислить значение ВыраженияОтношения.
2. Вызвать ПолучитьЗначение(Результата(1)).
3. Вычислить значение ВыраженияСдвига.
4. Вызвать ПолучитьЗначение(Результата(3)).
5. Произвести сравнение Результат(4) < Результат(2) (см. раздел 11.8.5).
6. Если Результат(5) равен undefined - вернуть false. Иначе вернуть Результат(5).
Значение нетерминала ВыражениеОтношения : ВыражениеОтношения <= ВыражениеСдвига вычисляется по следующей схеме:
1. Вычислить значение ВыраженияОтношения.
2. Вызвать ПолучитьЗначение(Результата(1)).
3. Вычислить значение ВыраженияСдвига.
4. Вызвать ПолучитьЗначение(Результата(3)).
5. Произвести сравнение Результат(4) < Результат(2) (см. раздел 11.8.5).
6. Если Результат(5) равен true или undefined - вернуть false. Иначе вернуть true.
Значение нетерминала ВыражениеОтношения : ВыражениеОтношения >= ВыражениеСдвига вычисляется по следующей схеме:
1. Вычислить значение ВыраженияОтношения.
2. Вызвать ПолучитьЗначение(Результата(1)).
3. Вычислить значение ВыраженияСдвига.
4. Вызвать ПолучитьЗначение(Результата(3)).
5. Произвести сравнение Результат(2) < Результат(4) (см. раздел 11.8.5).
6. Если Результат(5) равен true или undefined - вернуть false. Иначе вернуть true.
Сравнение x < y, где x и y являются значениями, возвращает true, false или undefined (последнее означает, что хотя бы один из операндов равен NaN). Такое сравнение производится следующим образом:
1. Вызвать ToPrimitive(x, подсказка Number).
2. Вызвать ToPrimitive(y, подсказка Number).
3. Если Тип(Результата(1)) равен String и Тип(Результата(2)) равен String - переход на шаг 16. (Заметим, что этот шаг отличается от шага 7 в алгоритме для оператора сложения + тем, что в нём используется и вместо или.)
4. Вызвать ToNumber(Результат(1)).
5. Вызвать ToNumber(Результат(2)).
6. Если Результат(4) равен NaN - вернуть undefined.
7. Если Результат(5) равен NaN - вернуть undefined.
8. Если Результат(4) и Результат(5) являются одинаковыми числовыми значениями - вернуть false.
9. Если Результат(4) равен +0 и Результат(5) равен -0 - вернуть false.
10. Если Результат(4) равен -0 и Результат(5) равен +0 - вернуть false.
11. Если Результат(4) равен +∞, вернуть false.
12. Если Результат(5) равен +∞, вернуть true.
13. Если Результат(5) равен -∞, вернуть false.
14. Если Результат(4) равен -∞, вернуть true.
15. Если математическое значение Результата (4) меньше, чем математическое значение Результата(5) (заметим, что эти математические значения оба конечны и не равны нулю) - вернуть true. Иначе вернуть false.
16. Если Результат(2) является префиксом Результата(1), вернуть false. (Строковое значение p является префиксом строкового значения q, если q может быть результатом конкатенации p и некоторой другой строки r. Отметим, что каждая строка является своим префиксом, т.к. r может быть пустой строкой.)
17. Если Результат(1) является префиксом Результата(2), вернуть true.
18. Пусть k - наименьшее неотрицательное число такое, что символ на позиции k Результата(1) отличается от символа на позиции k Результата(2). (Такое k должно существовать, т.к. на данном шаге установлено, что ни одна из строк не является префиксом другой.)
19. Пусть m - целое, равное юникодному коду символа на позиции k строки Результат(1).
20. Пусть n - целое, равное юникодному коду символа на позиции k строки Результат(2).
21. Если m < n, вернуть true. Иначе вернуть false.
ЗАМЕЧАНИЕ
Сравнение строк использует простой лексикографический порядок для последовательностей значений кодовых точек. Не предпринимается попыток использования более сложных, семантически ориентированных определений равенства строк или символов и схем упорядочения строк, описанных в спецификации Юникода. Таким образом, строки, которые являются канонически эквивалентными согласно стандарту Юникода, могут быть признаны неравными в ECMAScript. По сути, данный алгоритм предполагает, что строки уже находятся в нормализованной форме.
Значение нетерминала ВыражениеОтношения: ВыражениеОтношения instanceof ВыражениеСдвига вычисляется по следующей схеме:
1. Вычислить значение ВыраженияОтношения.
2. Вызвать ПолучитьЗначение(Результата(1)).
3. Вычислить значение ВыраженияСдвига.
4. Вызвать ПолучитьЗначение(Результата(3)).
5. Если Результат(4) не является объектом, бросить исключение TypeError.
6. Если для Результата(4) не реализован метод [[HasInstance]], бросить исключение TypeError.
7. Вызвать метод [[HasInstance]] Результата(4) с параметром Результат(2).
8.Вернуть Результат(7).
Значение нетерминала ВыражениеОтношения : ВыражениеОтношения in ВыражениеСдвига вычисляется по следующей схеме:
1. Вычислить значение ВыраженияОтношения.
2. Вызвать ПолучитьЗначение(Результата(1)).
3. Вычислить значение ВыраженияСдвига.
4. Вызвать ПолучитьЗначение(Результата(3)).
5. Если Результат(4) не является объектом, бросить исключение TypeError.
6. Вызвать ToString(Результат(2)).
7. Вызвать метод [[HasProperty]] Результата(4) с параметром Результат(6).
8.Вернуть Результат(7).
Синтаксис
Семантика
Результат вычисления значения оператора равенства всегда имеет тип Boolean и обозначает, существует ли определяемое оператором отношение между двумя операндами.
Значения нетерминалов ВыражениеРавенстваБезIn вычисляются по той же схеме, что и для нетерминалов ВыражениеРавенства за исключением того, что значения вложенных ВыраженияРавенстваБезIn и ВыражениеОтношенияБезIn вычисляются соответственно вместо вложенных ВыраженияРавенства и ВыраженияОтношения.
Значение нетерминала ВыражениеРавенства : ВыражениеРавенства == ВыражениеОтношения вычисляется по следующей схеме:
1. Вычислить ВыражениеРавенства.
2. Вызвать ПолучитьЗначение(Результата(1)).
3. Вычислить значение ВыраженияОтношения.
4. Вызвать ПолучитьЗначение(Результата(3)).
5. Выполнить сравнение Результат(4) == Результат(2) (см. раздел 11.9.3).
6. Вернуть Результат(5).
Значение нетерминала ВыражениеРавенства : ВыражениеРавенства != ВыражениеОтношения вычисляется по следующей схеме:
1. Вычислить ВыражениеРавенства.
2. Вызвать ПолучитьЗначение(Результата(1)).
3. Вычислить значение ВыраженияОтношения.
4. Вызвать ПолучитьЗначение(Результата(3)).
5. Выполнить сравнение Результат(4) == Результат(2) (см. раздел 11.9.3).
6. Если Результат(5) равен true - вернуть false. Иначе вернуть true.
Сравнение x == y, где x и y являются значениями, возвращает true или false. Такое сравнение производится следующим образом:
1. Если Тип(x) отличается от Типа(y) - переход на шаг 14.
2. Если Тип(x) равен Undefined - вернуть true.
3. Если Тип(x) равен Null - вернуть true.
4. Если Тип(x) не равен Number - переход на шаг 11.
5. Если x является NaN - вернуть false.
6. Если y является NaN - вернуть false.
7. Если x является таким же числовым значением, что и y, - вернуть true.
8. Если x равен +0, а y равен -0, вернуть true.
9. Если x равен -0, а y равен +0, вернуть true.
10. Вернуть false.
11. Если Тип(x) равен String - вернуть true, если x и y являются в точности одинаковыми последовательностями символов (имеют одинаковую длину и одинаковые символы в соответствующих позициях). Иначе вернуть false.
12. Если Тип(x) равен Boolean, вернуть true, если x и y оба равны true или оба равны false. Иначе вернуть false.
13. Вернуть true, если x и y ссылаются на один и тот же объект или они ссылаются на объекты, которые были объединены вместе (см. раздел 13.1.2). Иначе вернуть false.
14. Если x равно null, а y равно undefined - вернуть true.
15. Если x равно undefined, а y равно null - вернуть true.
16. Если Тип(x) равен Number, а Тип(y) равен String, вернуть результат сравнения x == ToNumber(y).
17. Если Тип(x) равен String, а Тип(y) равен Number, вернуть результат сравнения ToNumber(x)== y.
18. Если Тип(x) равен Boolean, вернуть результат сравнения ToNumber(x)== y.
19. Если Тип(y) равен Boolean, вернуть результат сравнения x == ToNumber(y).
20. Если Тип(x) - String или Number, а Тип(y) - Object, вернуть результат сравнения x == ToPrimitive(y).
21. Если Тип(x) - Object, а Тип(y) - String или Number, вернуть результат сравнения ToPrimitive(x)== y.
22. Вернуть false.
ЗАМЕЧАНИЕ
Для вышеприведённого определения равенства:
Сравнение можно принудительно сделать строковым: ""+a ==""+ b.
Сравнение можно принудительно сделать численным: a -0 ==b -0.
Сравнение можно принудительно сделать булевским: !a == !b.
Для операторов равенства сохраняются следующие инварианты:
A != B эквивалентно !(A == B).
A == B эквивалентно B == A за исключением порядка вычисления значений A и B.
Оператор равенства не всегда транзитивен. Например, могут существовать два различных объекта типа String, представляющих одно и то же значение; каждый из объектов типа String будет считаться равным строковому значению с точки зрения оператора ==, но два объекта String будут не равны друг другу.
Сравнение строк производит простую проверку равенства последовательностей значений кодов символов. Не предпринимается попыток использования более сложных, семантически ориентированных определений равенства строк или символов и схем упорядочения строк, описанных в спецификации Юникода версии 2.0. Таким образом, строки, которые являются канонически эквивалентными согласно стандарту Юникода, могут быть признаны не равными в ECMAScript. По сути, данный алгоритм предполагает, что строки уже находятся в нормализованной форме.
Значение нетерминала ВыражениеРавенства : ВыражениеРавенства === ВыражениеОтношения вычисляется по следующей схеме:
1. Вычислить ВыражениеРавенства.
2. Вызвать ПолучитьЗначение(Результата(1)).
3. Вычислить значение ВыраженияОтношения.
4. Вызвать ПолучитьЗначение(Результата(3)).
5. Выполнить сравнение Результат(4) === Результат(2) (См. ниже.)
6. Вернуть Результат(5).
Значение нетерминала ВыражениеРавенства : ВыражениеРавенства !== ВыражениеРавенства вычисляется по следующей схеме:
1. Вычислить ВыражениеРавенства.
2. Вызвать ПолучитьЗначение(Результата(1)).
3. Вычислить значение ВыраженияОтношения.
4. Вызвать ПолучитьЗначение(Результата(3)).
5. Выполнить сравнение Результат(4) === Результат(2) (См. ниже.)
6. Если Результат(5) равен true - вернуть false. Иначе вернуть true.
Сравнение x === y, где x и y являются значениями, возвращает true или false. Такое сравнение производится следующим образом:
1. Если Тип(x) отличается от Типа(y), вернуть false.
2. Если Тип(x) равен Undefined - вернуть true.
3. Если Тип(x) равен Null - вернуть true.
4. Если Тип(x) не равен Number - переход на шаг 11.
5. Если x является NaN - вернуть false.
6. Если y является NaN - вернуть false.
7. Если x является таким же числовым значением, что и y, - вернуть true.
8. Если x равен +0, а y равен -0 - вернуть true.
9. Если x равен -0, а y равен +0 - вернуть true.
10. Вернуть false.
11. Если Тип(x) равен String - вернуть true, если x и y являются в точности одинаковыми последовательностями символов (имеют одинаковую длину и одинаковые символы в соответствующих позициях). Иначе вернуть false.
12. Если Тип(x) равен Boolean, вернуть true, если x и y оба равны true или оба равны false. Иначе вернуть false.
13. Вернуть true, если x и y ссылаются на один и тот же объект или они ссылаются на объекты, которые были объединены вместе (см. раздел 13.1.2). Иначе вернуть false.
Синтаксис
Семантика
Значение нетерминала A : A @B, где @ - один из побитовых операторов в вышеперечисленных правилах, вычисляется следующим образом:
1. Вычислить значение A.
2. Вызвать ПолучитьЗначение(Результата(1)).
3. Вычислить значение B.
4. Вызвать ПолучитьЗначение(Результата(3)).
5. Вызвать ToInt32(Результат(2)).
6. Вызвать ToInt32(Результат(4)).
7. Применить побитовый оператор @ к Результату(5) и Результату(6). Результатом является знаковое 32-битное целое число.
8.Вернуть Результат(7).
Синтаксис
Семантика
Значение нетерминала ВыражениеЛогическогоИ : ВыражениеЛогическогоИ && ВыражениеПобитовогоИЛИ вычисляется по следующей схеме:
1. Вычислить значение ВыраженияЛогическогоИ.
2. Вызвать ПолучитьЗначение(Результата(1)).
3. Вызвать ToBoolean(Результат(2)).
4. Если Результат(3) равен false - вернуть Результат(2).
5. Вычислить значение ВыраженияПобитовогоИЛИ.
6. Вызвать ПолучитьЗначение(Результата(5)).
7. Вернуть Результат(6).
Значение нетерминала ВыражениеЛогическогоИЛИ : ВыражениеЛогическогоИЛИ || ВыражениеЛогическогоИ вычисляется по следующей схеме:
1. Вычислить значение ВыраженияЛогическогоИЛИ.
2. Вызвать ПолучитьЗначение(Результата(1)).
3. Вызвать ToBoolean(Результат(2)).
4. Если Результат(3) равен true - вернуть Результат(2).
5. Вычислить значение ВыраженияЛогическогоИ.
6. Вызвать ПолучитьЗначение(Результата(5)).
7. Вернуть Результат(6).
Значения нетерминалов ВыражениеЛогическогоИБезIn и ВыражениеЛогическогоИЛИБезIn вычисляются по той же схеме, что и для нетерминалов ВыражениеЛогическогоИ и ВыражениеЛогическогоИЛИ за исключением того, что значение вложенных ВыраженияЛогическогоИБезIn, ВыраженияПобитовогоИЛИБезIn и ВыраженияЛогическогоИЛИБезIn вычисляются соответственно вместо вложенных ВыраженияЛогическогоИ, ВыраженияПобитовогоИЛИ и ВыраженияЛогическогоИЛИ.
ЗАМЕЧАНИЕ
Значения, возвращаемые операторами && и ||, не обязательно имеют тип Boolean. Возвращаемое значение всегда будет иметь тип одного из двух выражений-операндов.
Синтаксис
Семантика
Значение нетерминала УсловноеВыражение : ВыражениеЛогическогоИЛИ ? ВыражениеПрисваивания : ВыражениеПрисваивания вычисляется по следующей схеме:
1. Вычислить значение ВыраженияЛогическогоИЛИ.
2. Вызвать ПолучитьЗначение(Результата(1)).
3. Вызвать ToBoolean(Результат(2)).
4. Если Результат(3) равен false - переход на шаг 8.
5. Вычислить значение первого ВыраженияПрисваивания.
6. Вызвать ПолучитьЗначение(Результата(5)).
7. Вернуть Результат(6).
8. Вычислить значение второго ВыраженияПрисваивания.
9. Вызвать ПолучитьЗначение(Результата(8)).
10. Вернуть Результат(9).
Значение нетерминала УсловноеВыражениеБезIn вычисляется по той же схеме, что и для нетерминала УсловноеВыражение за исключением того, что значения вложенных ВыраженияЛогическогоИЛИБезIn, ВыраженияПрисваивания, и ВыраженияПрисваиванияБезIn вычисляются соответственно вместо вложенных ВыраженияЛогическогоИЛИ, первого ВыраженияПрисваивания и второго ВыраженияПрисваивания.
ЗАМЕЧАНИЕ
Грамматика для УсловногоВыражения в ECMAScript немного отличается от таковой в языках C и Java, которые позволяют второму выражению быть Выражением, но требуют, чтобы третье выражение было УсловнымВаражением. Такое отличие было введено в ECMAScript, чтобы позволить обеим условным ветвям оказывать влияние на выражение присваивания, и чтобы устранить сбивающий с толку и довольно бесполезный случай использования запятой в качестве центрального выражения.
Синтаксис
Семантика
Значения нетерминалов ВыражениеПрисваиванияБезIn вычисляются по той же схеме, что и для нетерминалов ВыражениеПрисваивания за исключением того, что значения вложенных УсловногоВыраженияБезIn и ВыраженияПрисваиванияБезIn вычисляются соответственно вместо вложенных УсловногоВыражения и ВыраженияПрисваивания.
Значение нетерминала ВыражениеПрисваивания : ЛевостороннееВыражение = ВыражениеПрисваивания вычисляется по следующей схеме:
1. Вычислить значение ЛевостороннегоВыражения.
2. Вычислить значение ВыраженияПрисваивания.
3. Вызвать ПолучитьЗначение(Результат(2)).
4. Вызвать ЗаписатьЗначение(Результат(1), Результат(3)).
5. Вернуть Результат(3).
Значение нетерминала ВыражениеПрисваивания : ЛевостороннееВыражение @ = ВыражениеПрисваивания, где @ обозначает один из приведённых выше операторов, вычисляется по следующей схеме:
1. Вычислить значение ЛевостороннегоВыражения.
2. Вызвать ПолучитьЗначение(Результата(1)).
3. Вычислить значение ВыраженияПрисваивания.
4. Вызвать ПолучитьЗначение(Результата(3)).
5. Применить оператор @ к Результату(2) и Результату(4).
6. Вызвать ЗаписатьЗначение(Результат(1), Результат(5)).
7. Вернуть Результат(5).
Синтаксис
Семантика
Значение нетерминала Выражение : Выражение , ВыражениеПрисваивания вычисляется по следующей схеме:
1. Вычислить значение Выражения.
2. Вызвать ПолучитьЗначение(Результата(1)).
3. Вычислить значение ВыраженияПрисваивания.
4. Вызвать ПолучитьЗначение(Результата(3)).
5. Вернуть Результат(4).
Значение нетерминала ВыражениеБезIn вычисляется по той же схеме, что и для нетерминала Выражение за исключением того, что значения вложенных ВыраженияБезIn и ВыраженияПрисваиванияБезIn вычисляются соответственно вместо вложенных Выражения и ВыраженияПрисваивания.