ECMAScript | Язык ECMAScript: Операторы и Объявления

ECMAScript | Язык ECMAScript: Операторы и Объявления

Синтаксис Оператора

Statement [Yield, Await, Return] :

BlockStatement [?Yield, ?Await, ?Return]

VariableStatement [?Yield, ?Await]

EmptyStatement

ExpressionStatement [?Yield, ?Await]

IfStatement [?Yield, ?Await, ?Return]

BreakableStatement [?Yield, ?Await, ?Return]

ContinueStatement [?Yield, ?Await]

BreakStatement [?Yield, ?Await]

[+Return] ReturnStatement [?Yield, ?Await]

WithStatement [?Yield, ?Await, ?Return]

LabelledStatement [?Yield, ?Await, ?Return]

ThrowStatement [?Yield, ?Await]

TryStatement [?Yield, ?Await, ?Return]

DebuggerStatement

 

 

Синтаксис Объявления

Declaration [Yield, Await] :

HoistableDeclaration [?Yield, ?Await, ~Default]

ClassDeclaration [?Yield, ?Await, ~Default]

LexicalDeclaration [+In, ?Yield, ?Await]

 

Синтаксис Подъёмного Объявления

HoistableDeclaration [Yield, Await, Default] :

FunctionDeclaration [?Yield, ?Await, ?Default]

GeneratorDeclaration [?Yield, ?Await, ?Default]

AsyncFunctionDeclaration [?Yield, ?Await, ?Default]

AsyncGeneratorDeclaration [?Yield, ?Await, ?Default]

 

Синтаксис Оператора Прерывания

BreakableStatement [Yield, Await, Return] :

IterationStatement [?Yield, ?Await, ?Return]

SwitchStatement [?Yield, ?Await, ?Return]

 

14.1 Семантика операторов

 

14.1.1 Семантика времени выполнения: Оценка

HoistableDeclaration :

GeneratorDeclaration

AsyncFunctionDeclaration

AsyncGeneratorDeclaration

1. Вернуть NormalCompletion(empty).

 

HoistableDeclaration : FunctionDeclaration

1. Вернуть результат вычисления FunctionDeclaration.

 

BreakableStatement :

IterationStatement

SwitchStatement

1. Пусть newLabelSet будет новым пустым Списком.
2. Верните результат выполнения маркированной оценки LabelledEvaluation этого BreakableStatement с аргументом newLabelSet.

 

14.2 Блок

Синтаксис Блока

BlockStatement [Yield, Await, Return] :

Block [?Yield, ?Await, ?Return]

Block [Yield, Await, Return] :

{ StatementList [?Yield, ?Await, ?Return] opt }

StatementList [Yield, Await, Return] :

StatementListItem [?Yield, ?Await, ?Return]

StatementList [?Yield, ?Await, ?Return] StatementListItem [?Yield, ?Await, ?Return]

StatementListItem [Yield, Await, Return] :

Statement [?Yield, ?Await, ?Return]

Declaration [?Yield, ?Await]

 

14.2.1 Статическая семантика: Ранние Ошибки

Block : { StatementList }

 

14.2.2 Семантика времени выполнения: Оценка

Block : { }

1. Верните NormalCompletion(empty).

Block : { StatementList }

1. Пусть oldEnv будет лексической средой LexicalEnvironment текущего контекста выполнения.
2. Пусть blockEnv будет NewDeclarativeEnvironment(oldEnv).
3. Выполните создание экземпляра объявления блока BlockDeclarationInstantiation(StatementList, blockEnv).
4. Установите для LexicalEnvironment текущего контекста выполнения значение blockEnv.
5. Пусть blockValue будет результатом вычисления StatementList.
6. Установите LexicalEnvironment текущего контекста выполнения на oldEnv.
7. Вернуть значение blockValue.
Примечание 1

Независимо от того, как контроль покидает блок Block, LexicalEnvironment всегда возвращается в свое прежнее состояние.

StatementList : StatementList StatementListItem

1. Пусть sl будет результатом вычисления StatementList.
2. ReturnIfAbrupt(sl).
3. Пусть s будет результатом вычисления StatementListItem.
4. Вернуть завершение Completion(UpdateEmpty(s, sl)).
Примечание 2

Значение StatementList — это значение последнего порождающего значение элемента в StatementList. Например, все следующие вызовы функции eval возвращают значение 1:

eval("1;;;;;")
eval("1;{}")
eval("1;var a;")

 

14.2.3 BlockDeclarationInstantiation ( code, env )

Абстрактная операция BlockDeclarationInstantiation принимает аргументы code (узел синтаксического анализа) и env (декларативную запись среды).

code — это узел синтаксического анализа, соответствующий телу блока.

env — это запись среды, в которой должны быть созданы привязки.

Примечание

Когда блок Block или блок корпуса CaseBlock оцениваются, создается новая декларативная запись среды, и привязки для каждой переменной, константы, функции или класса, объявленные в блоке, создаются в записи среды.

При вызове она выполняет следующие шаги:

1. Пусть объявления declarations будут LexicallyScopedDeclarations для кода code.
2. Пусть privateEnv будет частной средой PrivateEnvironment текущего контекста выполнения.
3. Для каждого элемента d из объявлений declarations выполните
   а. Для каждого элемента dn из BoundNames из d выполните
      i. Если IsConstantDeclaration из d истинно (является true), то
         1. Выполнить ! env.CreateImmutableBinding(dn, true).
      ii. Иначе,
         1. Выполнить ! env.CreateMutableBinding(dn, false). ПРИМЕЧАНИЕ. Этот шаг заменен в разделе B.3.2.6.
   b. Если d - это FunctionDeclaration, GeneratorDeclaration, AsyncFunctionDeclaration или AsyncGeneratorDeclaration, тогда
      i. Пусть fn будет единственным элементом BoundNames из d.
      ii. Пусть fo будет InstantiateFunctionObject из d с аргументами env и privateEnv.
      iii. Выполните env.InitializeBinding(fn, fo). ПРИМЕЧАНИЕ. Этот шаг заменен в разделе B.3.2.6.

 

14.3 Объявления и оператор Переменной

14.3.1 Объявления Let и Const

Примечание

Объявления let и const определяют переменные, которые привязаны к «лексической среде» (LexicalEnvironment) текущего контекста выполнения. Переменные создаются при создании экземпляра содержащейся в них «записи среды«(Environment Record), но к ним нельзя получить доступ каким-либо образом до тех пор, пока не будет вычислена «лексическая привязка» (LexicalBinding) переменной. Переменной, определенной лексической привязкой LexicalBinding с инициализатором Initializer, присваивается значение «выражения присвоения» AssignmentExpression ее инициализатора Initializer при оценке LexicalBinding, а не при создании переменной. Если LexicalBinding в объявлении let не имеет инициализатора Initializer, переменной при оценке LexicalBinding присваивается значение undefined.

 

Синтаксис

LexicalDeclaration [In, Yield, Await] :

LetOrConst BindingList [?In, ?Yield, ?Await] ;

LetOrConst :

let

const

BindingList [In, Yield, Await] :

LexicalBinding [?In, ?Yield, ?Await]

BindingList [?In, ?Yield, ?Await] , LexicalBinding [?In, ?Yield, ?Await]

LexicalBinding [In, Yield, Await] :

BindingIdentifier [?Yield, ?Await] Initializer [?In, ?Yield, ?Await] opt

BindingPattern [?Yield, ?Await] Initializer [?In, ?Yield, ?Await]

 

14.3.1.1 Статическая семантика: ранние ошибки

LexicalDeclaration : LetOrConst BindingList ;

  • Это синтаксическая ошибка, если «Связанные Имена» BoundNames в BindingList содержит «let».
  • Это синтаксическая ошибка, если «Связанные Имена» BoundNames в BindingList содержит какие-либо повторяющиеся записи.

LexicalBinding : BindingIdentifier Initializer opt

14.3.1.2 Семантика времени выполнения: оценка

LexicalDeclaration : LetOrConst BindingList ;

1. Пусть next будет результатом вычисления списка привязки BindingList.
2. ReturnIfAbrupt(next).
3. Верните NormalCompletion(empty).

BindingList : BindingList , LexicalBinding

1. Пусть next будет результатом вычисления списка привязки BindingList.
2. ReturnIfAbrupt(next).
3. Верните результат вычисления LexicalBinding.

LexicalBinding : BindingIdentifier

1. Пусть lhs будет ResolveBinding(StringValue из BindingIdentifier).
2. Верните InitializeReferencedBinding(lhs, undefined).
Примечание

Правило статической семантики гарантирует, что эта форма лексической привязки LexicalBinding никогда не встречается в объявлении const.

LexicalBinding : BindingIdentifier Initializer

1. Пусть bindingId будет StringValue для BindingIdentifier.
2. Пусть lhs будет ResolveBinding(bindingId).
3. Если IsAnonymousFunctionDefinition(Initializer) истинно (является true), то
   а. Пусть значение value будет NamedEvaluation инициализатора Initializer с аргументом bindingId.
4. Иначе,
   а. Пусть rhs будет результатом вычисления инициализатора Initializer.
   b. Пусть value будет ? GetValue(rhs).
5. Верните InitializeReferencedBinding(lhs, value).

LexicalBinding : BindingPattern Initializer

1. Пусть rhs будет результатом вычисления инициализатора Initializer.
2. Пусть value будет ? GetValue(rhs).
3. Пусть env будет лексической средой (LexicalEnvironment) текущего контекста выполнения.
4. Верните результат выполнения BindingInitialization для BindingPattern, используя value и env в качестве аргументов.

 

14.3.2 Заявление о переменной

Примечание

Оператор var объявляет переменные, которые привязаны к «лексической среде» (LexicalEnvironment) текущего контекста выполнения. Переменные Var создаются при создании экземпляра содержащейся в них «записи среды«(Environment Record) и инициализируются значением undefined при создании. В рамках любой «переменной среды» (VariableEnvironment) общий «идентификатор привязки» (BindingIdentifier) может появляться более чем в одном «объявлении переменной» (VariableDeclaration), но эти объявления вместе определяют только одну переменную. Переменной, определенной с помощью VariableDeclaration с инициализатором Initializer, присваивается значение «Выражение присвоения» (AssignmentExpression) его инициализатора Initializer при выполнении VariableDeclaration, а не при создании переменной.

 

Синтаксис

VariableStatement [Yield, Await] :

var VariableDeclarationList [+In, ?Yield, ?Await] ;

VariableDeclarationList [In, Yield, Await] :

VariableDeclaration [?In, ?Yield, ?Await]

VariableDeclarationList [?In, ?Yield, ?Await] , VariableDeclaration [?In, ?Yield, ?Await]

VariableDeclaration [In, Yield, Await] :

BindingIdentifier [?Yield, ?Await] Initializer [?In, ?Yield, ?Await] opt

BindingPattern [?Yield, ?Await] Initializer [?In, ?Yield, ?Await]

 

14.3.2.1 Семантика времени выполнения: оценка

VariableStatement : var VariableDeclarationList ;

1. Пусть next будет результатом вычисления VariableDeclarationList.
2. ReturnIfAbrupt(next).
3. Верните NormalCompletion(empty).

VariableDeclarationList : VariableDeclarationList , VariableDeclaration

1. Пусть next будет результатом вычисления VariableDeclarationList.
2. ReturnIfAbrupt(next).
3. Верните результат вычисления VariableDeclaration.

VariableDeclaration : BindingIdentifier

1. Верните NormalCompletion(empty).

VariableDeclaration : BindingIdentifier Initializer

1. Пусть bindingId будет StringValue для BindingIdentifier.
2. Пусть lhs будет ? ResolveBinding(bindingId).
3. Если IsAnonymousFunctionDefinition(Initializer) истинно (является true), то
   а. Пусть значением будет NamedEvaluation инициализатора Initializer с аргументом bindingId.
4. Иначе,
   а. Пусть rhs будет результатом вычисления Initializer.
   b. Пусть value будет ? GetValue(rhs).
5. Вернуть ? PutValue(lhs, value).
Примечание

Если объявление переменной VariableDeclaration вложено в оператор with, а идентификатор привязки BindingIdentifier в VariableDeclaration совпадает с именем свойства привязки объекта Environment Record в операторе with, тогда на шаге 5 будет присвоено значение value свойству, а не привязке VariableEnvironment идентификатора Identifier.

VariableDeclaration : BindingPattern Initializer

1. Пусть rhs будет результатом вычисления Initializer.
2. Пусть rval будет ? GetValue(rhs).
3. Вернуть результат выполнения BindingInitialization для BindingPattern, передав rval и undefined в качестве аргументов.

 

14.3.3 Разрушение шаблонов привязки

Синтаксис

BindingPattern [Yield, Await] :

ObjectBindingPattern [?Yield, ?Await]

ArrayBindingPattern [?Yield, ?Await]

ObjectBindingPattern [Yield, Await] :

{ }

{ BindingRestProperty [?Yield, ?Await] }

{ BindingPropertyList [?Yield, ?Await] }

{ BindingPropertyList [?Yield, ?Await] , BindingRestProperty [?Yield, ?Await] opt }

ArrayBindingPattern [Yield, Await] :

[ Elision opt BindingRestElement [?Yield, ?Await] opt ]

[ BindingElementList [?Yield, ?Await] ]

[ BindingElementList [?Yield, ?Await] , Elision opt BindingRestElement [?Yield, ?Await] opt ]

BindingRestProperty [Yield, Await] :

BindingIdentifier [?Yield, ?Await]

BindingPropertyList [Yield, Await] :

BindingProperty [?Yield, ?Await]

BindingPropertyList [?Yield, ?Await] , BindingProperty [?Yield, ?Await]

BindingElementList [Yield, Await] :

BindingElisionElement [?Yield, ?Await]

BindingElementList [?Yield, ?Await] , BindingElisionElement [?Yield, ?Await]

BindingElisionElement [Yield, Await] :

Elision opt BindingElement [?Yield, ?Await]

BindingProperty [Yield, Await] :

SingleNameBinding [?Yield, ?Await]

PropertyName [?Yield, ?Await] : BindingElement [?Yield, ?Await]

BindingElement [Yield, Await] :

SingleNameBinding [?Yield, ?Await]

BindingPattern [?Yield, ?Await] Initializer [+In, ?Yield, ?Await] opt

SingleNameBinding [Yield, Await] :

BindingIdentifier [?Yield, ?Await] Initializer [+In, ?Yield, ?Await] opt

BindingRestElement [Yield, Await] :

BindingIdentifier [?Yield, ?Await]

BindingPattern [?Yield, ?Await]

 

14.3.3.1 Семантика времени выполнения: PropertyBindingInitialization — Инициализация Привязки Свойства

С параметрами value and environment.

Примечание

Они собирают список всех связанных имен свойств, а не просто пустое завершение.

BindingPropertyList : BindingPropertyList , BindingProperty

1. Пусть boundNames будет ? PropertyBindingInitialization из BindingPropertyList с аргументами value и environment.
2. Пусть nextNames будет ? PropertyBindingInitialization из BindingProperty с аргументами value и environment.
3. Верните конкатенацию списка boundNames и nextNames.

BindingProperty : SingleNameBinding

1. Пусть name будет строкой, которая является единственным элементом BoundNames из SingleNameBinding.
2. Выполнить ? KeyedBindingInitialization для SingleNameBinding с использованием value, environment и name (значения, среды и имени) в качестве аргументов.
3. Вернуть Список, единственным элементом которого является name.

BindingProperty : PropertyName : BindingElement

1. Пусть P будет результатом вычисления PropertyName.
2. ReturnIfAbrupt(P).
3. Выполнить ? KeyedBindingInitialization из BindingElement с value, environment и P в качестве аргументов.
4. Верните Список, единственным элементом которого является P.

 

14.3.3.2 Семантика времени выполнения: RestBindingInitialization — Инициализация Привязки Остатка

С параметрами value, environment и excludedNames.

BindingRestProperty :  BindingIdentifier

1. Пусть lhs будет ? ResolveBinding(StringValue из BindingIdentifier, environment).
2. Пусть restObj будет ! OrdinaryObjectCreate(%Object.prototype%).
3. Выполнить ? CopyDataProperties(restObj, value, excludedNames).
4. Если environment undefined, верните PutValue(lhs, restObj).
5. Верните InitializeReferencedBinding(lhs, restObj).

 

14.3.3.3 Семантика времени выполнения: KeyedBindingInitialization — Инициализация Привязки с Ключом

С параметрами value, environment и propertyName.

Примечание

Если для среды environment передается undefined, это означает, что для присвоения значения инициализации следует использовать операцию PutValue. Так обстоит дело со списками формальных параметров нестрогих функций. В этом случае привязки формальных параметров предварительно инициализируются, чтобы иметь дело с возможностью нескольких параметров с одним и тем же именем.

BindingElement : BindingPattern Initializer opt

1. Пусть v будет ? GetV(value, propertyName).
2. Если инициализатор Initializer присутствует и v является undefined (не определено), то
   а. Пусть defaultValue будет результатом оценки Initializer.
   b. Установите v на ? GetValue(defaultValue).
3. Верните результат выполнения BindingInitialization для BindingPattern, передав v и среду environment в качестве аргументов.

SingleNameBinding : BindingIdentifier Initializer opt

1. Пусть bindingId будет строковым значением StringValue для идентификатора привязки BindingIdentifier.
2. Пусть lhs будет ? ResolveBinding(bindingId, environment).
3. Пусть v будет? GetV(value, propertyName).
4. Если инициализатор Initializer присутствует и v является undefined (не определено), то
   а. Если IsAnonymousFunctionDefinition(Initializer) истинно (является true), то
      i. Установите v равным результату выполнения NamedEvaluation для инициализатора Initializer с аргументом bindingId.
   b. Иначе,
      i. Пусть defaultValue будет результатом оценки Initializer.
      ii. Установите v на ? GetValue(defaultValue).
5. Если среда environment является undefined (не определена), вернуть ? PutValue(lhs, v).
6. Верните InitializeReferencedBinding(lhs, v).

 

14.4 Оператор пустоты

Синтаксис

EmptyStatement :

;

14.4.1 Семантика времени выполнения: оценка

EmptyStatement : ;

1. Верните NormalCompletion(empty).

 

14.5 Оператор выражения

Синтаксис

ExpressionStatement [Yield, Await] :

[lookahead ∉ { {, function, async [не LineTerminator здесь] function, class, let [ }] Expression [+In, ?Yield, ?Await] ;

Примечание

ExpressionStatement не может начинаться с левой фигурной скобки { U+007B (LEFT CURLY BRACKET), потому что это может сделать его неоднозначным с производством блока Block.

ExpressionStatement не может начинаться с ключевых слов function или class (функции или класса), потому что это сделало бы его неоднозначным с FunctionDeclaration, GeneratorDeclaration или ClassDeclaration.

ExpressionStatement не может начинаться с async function (асинхронной функции), потому что это сделало бы его неоднозначным с AsyncFunctionDeclaration или AsyncGeneratorDeclaration.

ExpressionStatement не может начинаться с последовательности из двух токенов let [, потому что это сделало бы его неоднозначным с let LexicalDeclaration, первая LexicalBinding которой была ArrayBindingPattern.

14.5.1 Семантика времени выполнения: оценка

ExpressionStatement : Expression ;

1. Пусть exprRef будет результатом вычисления Expression.
2. Вернуть ? GetValue(exprRef).

 

14.6 Оператор if

Синтаксис

IfStatement [Yield, Await, Return] :

if ( Expression [+In, ?Yield, ?Await] ) Statement [?Yield, ?Await, ?Return] else Statement [?Yield, ?Await, ?Return]

if ( Expression [+In, ?Yield, ?Await] ) Statement [?Yield, ?Await, ?Return] [lookahead ≠ else]

Примечание

Ограничение просмотра вперед [lookahead ≠ else] решает классическую проблему «висящего ИНАЧЕ» обычным способом. То есть, когда выбор связанного if в остальном неоднозначен, else связан с ближайшим (самым внутренним) из кандидата if.

14.6.1 Статическая семантика: Ранние Ошибки

IfStatement : if ( Expression ) Statement else Statement

  • Это синтаксическая ошибка, если IsLabelledFunction(первое утверждение Statement) истинно (является true).
  • Это синтаксическая ошибка, если IsLabelledFunction(второе утверждение Statement) истинно (является true).

IfStatement : if ( Expression ) Statement

Примечание

Это правило необходимо применять только в том случае, если реализовано расширение, указанное в B.3.1.

14.6.2 Семантика времени выполнения: Оценка

IfStatement : if ( Expression ) Statement else Statement

1. Пусть exprRef будет результатом вычисления Expression.
2. Пусть exprValue будет ! ToBoolean(? GetValue(exprRef)).
3. Если exprValue истинно (является true), тогда
   а. Пусть stmtCompletion будет результатом вычисления первого утверждения Statement.
4. Иначе,
   а. Пусть stmtCompletion будет результатом вычисления второго утверждения Statement.
5. Вернуть завершение Completion(UpdateEmpty(stmtCompletion, undefined)).

IfStatement : if ( Expression ) Statement

1. Пусть exprRef будет результатом вычисления Expression.
2. Пусть exprValue будет ! ToBoolean(? GetValue(exprRef)).
3. Если exprValue ложно (является false), тогда
   а. Вернуть NormalCompletion(undefined).
4. Иначе,
   а. Пусть stmtCompletion будет результатом вычисления Statement.
b. Вернуть Завершение Completion(UpdateEmpty(stmtCompletion, undefined)).

 

14.7 Операторы итерации

Синтаксис операторов итерации

IterationStatement [Yield, Await, Return] :

DoWhileStatement [?Yield, ?Await, ?Return]

WhileStatement [?Yield, ?Await, ?Return]

ForStatement [?Yield, ?Await, ?Return]

ForInOfStatement [?Yield, ?Await, ?Return]

 

14.7.1 Семантики

14.7.1.1 LoopContinues ( completion, labelSet )

Абстрактная операция LoopContinues принимает аргументы completion и labelSet. На русском эта функция выглядит примерно так «Цикл продолжается (завершение, набор меток)«.

При вызове она выполняет следующие шаги:

1. Если completion.[[Type]] является normal, вернуть true.
2. Если completion.[[Type]] не является continue, вернуть false.
3. Если completion.[[Target]] является empty, вернуть true.
4. Если completion.[[Target]] является элементом из labelSet, вернуть true.
5. Вернуть false.
Примечание

В части Statement из IterationStatement можно использовать ContinueStatement для начала новой итерации.

 

Семантика времени выполнения: оценка цикла

С параметром labelSet.

IterationStatement : DoWhileStatement

Вернуть ? DoWhileLoopEvaluation из DoWhileStatement с аргументом labelSet.

IterationStatement : WhileStatement

 ? WhileLoopEvaluation из WhileStatement с аргументом labelSet.

IterationStatement : ForStatement

 ? ForLoopEvaluation из ForStatement с аргументом labelSet.

IterationStatement : ForInOfStatement

 ? ForInOfLoopEvaluation из ForInOfStatement с аргументом labelSet.

 

14.7.2 Оператор do-while

Синтаксис оператора do-while

DoWhileStatement [Yield, Await, Return] :

do Statement [?Yield, ?Await, ?Return] while ( Expression [+In, ?Yield, ?Await] ) ;

 

14.7.2.1 Статическая семантика: Ранние Ошибки

DoWhileStatement : do Statement while ( Expression ) ;

Если IsLabelledFunction(Statement) истинно true, это синтаксическая ошибка.

Примечание

Это правило необходимо применять только в том случае, если реализовано расширение, указанное в B.3.2.

 

14.7.2.2 Семантика времени выполнения: DoWhileLoopEvaluation

С параметром labelSet.

DoWhileStatement : do Statement while ( Expression ) ;

1. Пусть V будет undefined.
Повторять,
 stmtResult будет результатом оценки Statement.
Если LoopContinues(stmtResultlabelSet) является false, вернуть Completion(UpdateEmpty(stmtResultV)).
Если stmtResult.[[Value]] не является empty, установить V на stmtResult.[[Value]].
 exprRef будет результатом оценки Expression.
 exprValue будет ? GetValue(exprRef).
 ! ToBoolean(exprValue) является false, вернуть NormalCompletion(V).

 

14.7.3 Оператор while

Синтаксис оператора while

WhileStatement [Yield, Await, Return] :

while ( Expression [+In, ?Yield, ?Await] ) Statement [?Yield, ?Await, ?Return]

14.7.3.1 Статическая семантика: Ранние Ошибки

WhileStatement : while ( Expression ) Statement

Примечание

Это правило необходимо применять только в том случае, если реализовано расширение, указанное в разделе B.3.1.

 

14.7.3.2 Семантика времени выполнения: WhileLoopEvaluation

С параметром labelSet.

WhileStatement : while ( Expression ) Statement

1. Пусть V будет undefined.
2. Повторять,
   a. Пусть exprRef будет результатом вычисления Expression.
   b. Пусть exprValue будет ? GetValue(exprRef).
   c. Если ! ToBoolean(exprValue) является false, вернуть NormalCompletion(V).
   d. Пусть stmtResult будет результатом вычисления Statement.
   e. Если LoopContinues(stmtResult, labelSet) является false, вернуть Completion(UpdateEmpty(stmtResult, V)).
   f. Если stmtResult.[[Value]] не является empty, установить V на stmtResult.[[Value]].

 

14.7.4 Оператор for

Синтаксис

ForStatement [Yield, Await, Return] :

for ( [ lookahead ≠ let [ ] Expression [~In, ?Yield, ?Await] opt ; Expression [+In, ?Yield, ?Await] opt ; Expression [+In, ?Yield, ?Await] opt ) Statement [?Yield, ?Await, ?Return]

for ( var VariableDeclarationList [~In, ?Yield, ?Await] ; Expression [+In, ?Yield, ?Await] opt ; Expression [+In, ?Yield, ?Await] opt ) Statement [?Yield, ?Await, ?Return]

for ( LexicalDeclaration [~In, ?Yield, ?Await] Expression [+In, ?Yield, ?Await] opt ; Expression [+In, ?Yield, ?Await] opt ) Statement [?Yield, ?Await, ?Return]

14.7.4.1 Статическая семантика: Ранние Ошибки

ForStatement :

for ( Expression opt ; Expression opt ; Expression opt ) Statement

for ( var VariableDeclarationList ; Expression opt ; Expression opt ) Statement

for ( LexicalDeclaration Expression opt ; Expression opt ) Statement

 

Примечание

Это правило необходимо применять только в том случае, если реализовано расширение, указанное в разделе B.3.1.

 

ForStatement : for ( LexicalDeclaration Expression opt ; Expression opt ) Statement

 

14.7.4.2 Семантика времени выполнения: ForLoopEvaluation

С параметром labelSet.

ForStatement : for ( Expression opt ; Expression opt ; Expression opt ) Statement

1. Если первое выражение Expression присутствует, то
   a. Пусть exprRef будет результатом вычисления первого выражения Expression.
   b. Выполнить ? GetValue(exprRef).
2. Вернуть ? ForBodyEvaluation(второе выражение Expression, третье выражение Expression, определение Statement, «», labelSet).

ForStatement : for ( var VariableDeclarationList ; Expression opt ; Expression opt ) Statement

1. Пусть varDcl будет результатом вычисления VariableDeclarationList.
2. ReturnIfAbrupt(varDcl).
3. Вернуть ? ForBodyEvaluation(первое выражение Expression, второе выражение Expression, определение Statement, «», labelSet).

ForStatement : for ( LexicalDeclaration Expression opt ; Expression opt ) Statement

1. Пусть oldEnv будет LexicalEnvironment(Лексическая среда) текущего контекста выполнения.
2. Пусть loopEnv будет NewDeclarativeEnvironment(oldEnv).
3. Пусть isConst будет IsConstantDeclaration из LexicalDeclaration.
4. Пусть boundNames будет BoundNames из LexicalDeclaration.
5. Для каждого элемента dn из boundNames выполните
   a. Если isConst является true, тогда
      i. Выполнить ! loopEnv.CreateImmutableBinding(dn, true).
   b. Иначе,
      i. Выполнить ! loopEnv.CreateMutableBinding(dn, false).
6. Установите для LexicalEnvironment(Лексическая среда) текущего контекста выполнения значение loopEnv.
7. Пусть forDcl будет результатом вычисления LexicalDeclaration.
8. Если forDcl является внезапным завершением, тогда
   a. Установите для LexicalEnvironment текущего контекста выполнения значение oldEnv.
   b. Вернуть Completion(forDcl).
9. Если isConst имеет значение false, пусть perIterationLets будет boundNames; в противном случае пусть perIterationLets будет «».
10. Пусть bodyResult будет ForBodyEvaluation(первое выражение Expression, второе выражение Expression, определение Statement, perIterationLets, labelSet).
11. Установите для LexicalEnvironment текущего контекста выполнения значение oldEnv.
12. Вернуть Завершение Completion(bodyResult).

 

14.7.4.3 ForBodyEvaluation ( test, increment, stmt, perIterationBindings, labelSet )

Абстрактная операция ForBodyEvaluation принимает аргументы test, increment, stmt, perIterationBindings и labelSet. При вызове она выполняет следующие шаги:

1. Пусть V будет undefined.
2. Выполнить ? CreatePerIterationEnvironment(perIterationBindings).
3. Повторять,
   a. Если тест не [empty], то
      i. Пусть testRef будет результатом оценки test.
      ii. Пусть testValue будет ? GetValue(testRef).
      iii. Если ! ToBoolean(testValue) является false, вернуть NormalCompletion(V).
   b. Пусть result будет результатом вычисления stmt.
   c. Если LoopContinues(result, labelSet) имеет значение false, вернуть Completion(UpdateEmpty(result, V)).
   d. Если result.[[Value]] не empty, установите V равным result.[[Value]].
   e. Выполнить ? CreatePerIterationEnvironment(perIterationBindings).
   f. Если инкремент increment не [empty], то
      i. Пусть incRef будет результатом вычисления приращения increment.
      ii. Выполнить ? GetValue(incRef).

 

14.7.4.4 CreatePerIterationEnvironment ( perIterationBindings )

Абстрактная операция CreatePerIterationEnvironment принимает аргумент perIterationBindings. При вызове она выполняет следующие шаги:

1. Если в perIterationBindings есть какие-либо элементы, то
   a. Пусть lastIterationEnv будет LexicalEnvironment текущего контекста выполнения.
   b. Пусть outer будет lastIterationEnv.[[OuterEnv]].
   c. Утверждено: outer не равен null.
   d. Пусть thisIterationEnv будет NewDeclarativeEnvironment(outer).
   e. Для каждого элемента bn из perIterationBindings выполните
      i. Выполнить ! thisIterationEnv.CreateMutableBinding(bn, false).
      ii. Пусть lastValue будет ? lastIterationEnv.GetBindingValue(bn, true).
      iii. Выполнить thisIterationEnv.InitializeBinding(bn, lastValue).
   f. Установите для LexicalEnvironment текущего контекста выполнения значение thisIterationEnv.
2. Вернуть undefined.

 

 

14.7.5 Оператор for-in, for-of, for-await-of

Синтаксис

ForInOfStatement [Yield, Await, Return] :

for ( [ lookahead ≠ let [ ] LeftHandSideExpression [?Yield, ?Await] in Expression [+In, ?Yield, ?Await] ) Statement [?Yield, ?Await, ?Return]

for ( var ForBinding [?Yield, ?Await] in Expression [+In, ?Yield, ?Await] ) Statement [?Yield, ?Await, ?Return]

for ( ForDeclaration [?Yield, ?Await] in Expression [+In, ?Yield, ?Await] ) Statement [?Yield, ?Await, ?Return]

for ( [ lookahead ∉ { let, async of  }] LeftHandSideExpression [?Yield, ?Await] of AssignmentExpression [+In, ?Yield, ?Await] ) Statement [?Yield, ?Await, ?Return]

for ( var ForBinding [?Yield, ?Await] of AssignmentExpression [+In, ?Yield, ?Await] ) Statement [?Yield, ?Await, ?Return]

for ( ForDeclaration [?Yield, ?Await] of AssignmentExpression [+In, ?Yield, ?Await] ) Statement [?Yield, ?Await, ?Return]

[+Await] for await ( [lookahead ≠ let] LeftHandSideExpression [?Yield, ?Await] of AssignmentExpression [+In, ?Yield, ?Await] ) Statement [?Yield, ?Await, ?Return]

[+Await] for await ( var ForBinding [?Yield, ?Await] of AssignmentExpression [+In, ?Yield, ?Await] ) Statement [?Yield, ?Await, ?Return]

[+Await] for await ( ForDeclaration [?Yield, ?Await] of AssignmentExpression [+In, ?Yield, ?Await] ) Statement [?Yield, ?Await, ?Return]

ForDeclaration [Yield, Await] :

LetOrConst ForBinding [?Yield, ?Await]

ForBinding [Yield, Await] :

BindingIdentifier [?Yield, ?Await]

BindingPattern [?Yield, ?Await]

 

Примечание

Этот раздел расширен Приложением B.3.5.

 

14.7.5.1 Статическая семантика: Ранние Ошибки

ForInOfStatement :

for ( LeftHandSideExpression in Expression ) Statement

for ( var ForBinding in Expression ) Statement

for ( ForDeclaration in Expression ) Statement

for ( LeftHandSideExpression of AssignmentExpression ) Statement

for ( var ForBinding of AssignmentExpression ) Statement

for ( ForDeclaration of AssignmentExpression ) Statement

for await ( LeftHandSideExpression of AssignmentExpression ) Statement

for await ( var ForBinding of AssignmentExpression ) Statement

for await ( ForDeclaration of AssignmentExpression ) Statement

Примечание

Это правило необходимо применять только в том случае, если реализовано расширение, указанное в разделе B.3.1.

 

ForInOfStatement :

for ( LeftHandSideExpression in Expression ) Statement

for ( LeftHandSideExpression of AssignmentExpression ) Statement

for await ( LeftHandSideExpression of AssignmentExpression ) Statement

Если LeftHandSideExpression является ObjectLiteral или ArrayLiteral, применяются следующие правила Ранней Ошибки:

Если LeftHandSideExpression не является ни ObjectLiteral, ни ArrayLiteral, применяется следующее правило Ранней Ошибки:

ForInOfStatement :

for ( ForDeclaration in Expression ) Statement

for ( ForDeclaration of AssignmentExpression ) Statement

for await ( ForDeclaration of AssignmentExpression ) Statement

 

14.7.5.2 Статическая семантика: IsDestructuring

MemberExpression : PrimaryExpression

1. Если PrimaryExpression является ObjectLiteral или ArrayLiteral, верните true.
2. Вернуть false.

MemberExpression :

MemberExpression [ Expression ]

MemberExpression . IdentifierName

MemberExpression TemplateLiteral

SuperProperty

MetaProperty

new MemberExpression Arguments

NewExpression :

new NewExpression

LeftHandSideExpression :

CallExpression

OptionalExpression

1. Вернуть false.

ForDeclaration : LetOrConst ForBinding

1. Вернуть IsDestructuring из ForBinding.

ForBinding : BindingIdentifier

1. Вернуть false.

ForBinding : BindingPattern

1. Вернуть true.
Примечание

Этот раздел расширен Приложением B.3.5

 

14.7.5.3 Семантика времени выполнения: ForDeclarationBindingInitialization

С параметрами value и environment.

Примечание

undefined передается для среды environment, чтобы указать, что для присвоения значения инициализации следует использовать операцию PutValue. Так обстоит дело с операторами var и списками формальных параметров некоторых нестрогих функций (смотри раздел 10.2.11). В этих случаях лексическая привязка поднимается и пре-инициализируется до оценки ее инициализатора.

ForDeclaration : LetOrConst ForBinding

1. Верните результат выполнения BindingInitialization для ForBinding, передав значение value и среду environment в качестве аргументов.

 

14.7.5.4 Семантика времени выполнения: ForDeclarationBindingInstantiation

С параметром environment.

ForDeclaration : LetOrConst ForBinding

1. Утверждено: среда environment - это декларативная запись среды.
2. Для каждого элемента name из связанных имён BoundNames из ForBinding выполните
   a. Если IsConstantDeclaration из LetOrConst истинно true, то
      i. Выполнить ! environment.CreateImmutableBinding(name, true).
   b. Иначе,
      i. Выполнить ! environment.CreateMutableBinding(name, false).

 

14.7.5.5 Семантика времени выполнения: ForInOfLoopEvaluation

С параметром labelSet.

ForInOfStatement : for ( LeftHandSideExpression in Expression ) Statement

1. Пусть keyResult будет ? ForIn/OfHeadEvaluation(« », Expression, enumerate).
2. Вернуть ? ForIn/OfBodyEvaluation (LeftHandSideExpression, Statement, keyResultenumerateassignmentlabelSet).

ForInOfStatement : for ( var ForBinding in Expression ) Statement

1. Пусть keyResult будет ? ForIn/OfHeadEvaluation(« », Expression, enumerate).
2. Вернуть ? ForIn/OfBodyEvaluation(ForBindingStatementkeyResultenumeratevarBindinglabelSet).

ForInOfStatement : for ( ForDeclaration in Expression ) Statement

1. Пусть keyResult будет ? ForIn/OfHeadEvaluation(BoundNames из ForDeclaration, Expression, enumerate).
2. Вернуть ? ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult, enumerate, lexicalBinding, labelSet).

ForInOfStatement : for ( LeftHandSideExpression of AssignmentExpression ) Statement

1.Пусть keyResult будет ? ForIn/OfHeadEvaluation(« », AssignmentExpression, iterate).
2. Вернуть ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement, keyResult, iterate, assignment, labelSet).

ForInOfStatement : for ( var ForBinding of AssignmentExpression ) Statement

1. Пусть keyResult будет ? ForIn/OfHeadEvaluation(« », AssignmentExpression, iterate).
2. Вернуть ? ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult, iterate, varBinding, labelSet).

ForInOfStatement : for ( ForDeclaration of AssignmentExpression ) Statement

1. Пусть keyResult будет ? ForIn/OfHeadEvaluation(BoundNames из ForDeclaration, AssignmentExpression, iterate).
2. Вернуть ? ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult, iterate, lexicalBinding, labelSet).

ForInOfStatement : for await ( LeftHandSideExpression of AssignmentExpression ) Statement

1. Пусть keyResult будет ? ForIn/OfHeadEvaluation(« », AssignmentExpression, async-iterate).
2. Вернуть ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement, keyResult, iterate, assignment, labelSet, async).

ForInOfStatement : for await ( var ForBinding of AssignmentExpression ) Statement

1. Пусть keyResult будет ? ForIn/OfHeadEvaluation(« », AssignmentExpression, async-iterate).
2. Вернуть ? ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult, iterate, varBinding, labelSet, async).

ForInOfStatement : for await ( ForDeclaration of AssignmentExpression ) Statement

1. Пусть keyResult будет ? ForIn/OfHeadEvaluation(BoundNames из ForDeclaration, AssignmentExpression, async-iterate).
2. Вернуть ? ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult, iterate, lexicalBinding, labelSet, async).
Примечание

Этот раздел расширен Приложением B.3.5.

 

14.7.5.6 ForIn/OfHeadEvaluation ( uninitializedBoundNames, expr, iterationKind )

Абстрактная операция ForIn/OfHeadEvaluation принимает аргументы uninitializedBoundNames, expr и iterationKind (такой как enumerate, iterate или async-iterate). При вызове она выполняет следующие шаги:

1. Пусть oldEnv будет LexicalEnvironment текущего контекста выполнения.
2. Если uninitializedBoundNames не является пустым Списком, тогда
   а. Утверждено: uninitializedBoundNames не имеет повторяющихся записей.
   b. Пусть newEnv будет NewDeclarativeEnvironment(oldEnv).
   c. Для каждого строкового имени name из uninitializedBoundNames выполните
      i. Выполнять ! newEnv.CreateMutableBinding(name, false).
   d. Установите для LexicalEnvironment текущего контекста выполнения значение newEnv.
3. Пусть exprRef будет результатом вычисления expr.
4. Установите LexicalEnvironment текущего контекста выполнения на oldEnv.
5. Пусть exprValue будет ? GetValue(exprRef).
6. Если iterationKind является enumerate, тогда
   а. Если exprValue является undefined(не определено) или равно null, тогда
      i. Вернуть Завершение Completion { [[Type]]: break, [[Value]]: empty, [[Target]]: empty }.
   b. Пусть obj будет ! ToObject(exprValue).
   c. Пусть iterator будет ? EnumerateObjectProperties (obj).
   d. Пусть nextMethod будет ! GetV(iterator, "next").
   е. Вернуть запись Record {[[Iterator]]: iterator, [[NextMethod]]: nextMethod, [[Done]]: false}.
7. Иначе,
   а. Утверждено: iterationKind является iterate или async-iterate.
   b. Если iterationKind является async-iterate, пусть iteratorHint будет async.
   c. В противном случае пусть iteratorHint будет sync.
   d. Вернуть ? GetIterator (exprValue, iteratorHint).

 

14.7.5.7 ForIn/OfBodyEvaluation ( lhs, stmt, iteratorRecord, iterationKind, lhsKind, labelSet [ , iteratorKind ] )

Абстрактная операция ForIn/OfBodyEvaluation принимает аргументы lhs, stmt, iteratorRecord, iterationKind, lhsKind (такой как assignment, varBinding или lexicalBinding), а также labelSet и необязательный аргумент iteratorKind (такой как sync или async). При вызове она выполняет следующие шаги:

1. Если iteratorKind отсутствует, установите для iteratorKind значение sync.
2. Пусть oldEnv будет LexicalEnvironment текущего контекста выполнения.
3. Пусть V является undefined(не определено).
4. Пусть деструктуризация destructuring будет IsDestructuring из lhs.
5. Если destructuring является true (истинно) и если lhsKind является assignment, то
  а. Утверждено: lhs - это выражение LeftHandSideExpression.
  b. Пусть assignmentPattern будет AssignmentPattern, который покрывается lhs.
6. Повторите,
  а. Пусть nextResult будет ? Вызов (iteratorRecord.[[NextMethod]], iteratorRecord.[[Iterator]]).
  b. Если iteratorKind является async, установите для nextResult значение ? Ожидайте Await(nextResult).
  c. Если Тип Type(nextResult) не является Object, вызовите исключение TypeError.
  d. Пусть done будет ? IteratorComplete(nextResult).
  e. Если done является true (истинно), вернуть NormalCompletion(V).
  f. Пусть nextValue будет ? IteratorValue(nextResult).
  g. Если lhsKind является либо assignment, либо varBinding, тогда
    i. Если destructuring является false (ложна), то
      1. Пусть lhsRef будет результатом вычисления lhs.(Это может быть оценено повторно.)
  h. Иначе,
    i. Утверждено: lhsKind - это lexicalBinding.
    ii. Утверждено: lhs - это ForDeclaration.
    iii. Пусть iterationEnv будет NewDeclarativeEnvironment(oldEnv).
    iv. Выполните ForDeclarationBindingInstantiation для lhs с передачей iterationEnv в качестве аргумента.
    v. Установите для LexicalEnvironment текущего контекста выполнения значение iterationEnv.
    vi. Если destructuring является false (ложна), то
      1. Утверждено: lhs связывает одно имя.
      2. Пусть lhsName будет единственным элементом BoundNames из lhs.
      3. Пусть lhsRef будет ! ResolveBinding(lhsName).
  i. Если destructuring является false (ложна), то
    i. Если lhsRef является внезапным завершением, то
      1. Пусть status будет lhsRef.
    ii. Иначе, если lhsKind является lexicalBinding, тогда
      1. Пусть status будет InitializeReferencedBinding(lhsRef, nextValue).
    iii. Иначе,
      1. Пусть status будет PutValue(lhsRef, nextValue).
  j. Иначе,
    i. Если lhsKind является assignment (присваивание), тогда
      1. Пусть status будет DestructuringAssignmentEvaluation для assignmentPattern с аргументом nextValue.
    ii. Иначе, если lhsKind является varBinding, тогда
      1. Утверждено: lhs - это ForBinding.
      2. Пусть status будет BindingInitialization из lhs с аргументами nextValue и undefined.
    iii. Иначе,
      1. Утверждено: lhsKind является lexicalBinding (лексическим связыванием).
      2. Утверждено: lhs - это ForDeclaration.
      3. Пусть status будет ForDeclarationBindingInitialization из lhs с аргументами nextValue и iterationEnv.
  k. Если status является внезапным завершением, то
    i. Установите для LexicalEnvironment текущего контекста выполнения значение oldEnv.
    ii. Если iteratorKind является async, вернуть ? AsyncIteratorClose(iteratorRecord, status).
    iii. Если iterationKind является enumerate (перечислим), то
      1. Верните status.
    iv. Иначе,
      1. Утверждено: iterationKind является iterate.
      2. Вернуть ? IteratorClose(iteratorRecord, status).
  l. Пусть result будет результатом вычисления stmt.
  m. Установите для LexicalEnvironment текущего контекста выполнения значение oldEnv.
  n. Если LoopContinues(result, labelSet) является false (ложно), то
    i. Если iterationKind является enumerate (перечислим), то
      1. Вернуть Завершение (UpdateEmpty(result, V)).
    ii. Иначе,
      1. Утверждено: iterationKind является iterate.
      2. Установите status UpdateEmpty(result, V).
      3. Если iteratorKind является async, вернуть ? AsyncIteratorClose(iteratorRecord, status).
      4. Вернуть ? IteratorClose(iteratorRecord, status).
  о. Если result.[[Value]] не является empty, установите V равным result.[[Value]].

 

14.7.5.8 Семантика времени выполнения: Оценка

ForBinding : BindingIdentifier

1. Пусть bindingId будет StringValue для BindingIdentifier.
2. Вернуть ? ResolveBinding(bindingId).

 

14.7.5.9 EnumerateObjectProperties ( O )

Абстрактная операция EnumerateObjectProperties принимает аргумент O (объект). При вызове она выполняет следующие шаги:

1. Вернуть объект Iterator (27.1.1.2), метод next которого выполняет итерацию по всем ключам со значением String перечислимых свойств O. Объект итератора никогда не доступен напрямую для кода ECMAScript. Механика и порядок перечисления свойств не указаны, но должны соответствовать правилам, указанным ниже.

Методы throw и return итератора имеют значение null и никогда не вызываются. Метод next итератора обрабатывает свойства объекта, чтобы определить, должен ли ключ свойства возвращаться как значение итератора. Возвращенные ключи свойств не включают ключи, которые являются символами. Свойства целевого объекта могут быть удалены во время перечисления. Свойство, которое удаляется перед обработкой методом next итератора, игнорируется. Если новые свойства добавляются к целевому объекту во время перечисления, не гарантируется, что новые добавленные свойства будут обработаны в активном перечислении. Имя свойства будет возвращено методом next итератора не более одного раза в любом перечислении.

 

 

Перечисление свойств целевого объекта включает рекурсивное перечисление свойств его прототипа, прототипа прототипа и так далее; но свойство прототипа не обрабатывается, если оно имеет то же имя, что и свойство, которое уже было обработано методом next итератора. Значения атрибутов [[Enumerable]] не учитываются при определении того, было ли уже обработано свойство объекта-прототипа. Имена перечислимых свойств объектов-прототипов должны быть получены путем вызова EnumerateObjectProperties, передавая объект-прототип в качестве аргумента. EnumerateObjectProperties должен получить собственные ключи свойств целевого объекта, вызвав его внутренний метод [[OwnPropertyKeys]]. Атрибуты свойства целевого объекта должны быть получены путем вызова его внутреннего метода [[GetOwnProperty]].

Кроме того, если ни O, ни какой-либо объект в его цепочке прототипов не является экзотическим прокси-объектом, экзотическим объектом с целочисленным индексом, экзотическим объектом пространства имен модуля или реализацией, предоставленной экзотическим объектом, то итератор должен вести себя так же, как итератор, заданный CreateForInIterator(O) до тех пор, пока не произойдет одно из следующих событий:

  • значение внутреннего слота [[Prototype]] для O или объекта в его цепочке прототипов изменяется,
  • свойство удаляется из O или объекта в его цепочке прототипов,
  • свойство добавляется к объекту в цепочке прототипов O, или
  • значение атрибута [[Enumerable]] свойства объекта O или объекта в его цепочке прототипов изменяется.

 

Примечание 1

Реализации ECMAScript не требуются для реализации алгоритма из 14.7.5.10.2.1 напрямую. Они могут выбрать любую реализацию, поведение которой не будет отклоняться от этого алгоритма, если не нарушено одно из ограничений в предыдущем абзаце.

Ниже приводится информативное определение функции генератора ECMAScript, которая соответствует этим правилам:

function* EnumerateObjectProperties(obj) {
   const visited = new Set();
   for (const key of Reflect.ownKeys(obj)) {
      if (typeof key === "symbol") continue;
      const desc = Reflect.getOwnPropertyDescriptor(obj, key);
      if (desc) {
         visited.add(key);
         if (desc.enumerable) yield key;
      }
   }
   const proto = Reflect.getPrototypeOf(obj);
   if (proto === null) return;
   for (const protoKey of EnumerateObjectProperties(proto)) {
      if (!visited.has(protoKey)) yield protoKey;
   }
}

 

Примечание 2

Список экзотических объектов, для которых не требуется, чтобы реализации соответствовали CreateForInIterator, был выбран потому, что реализации исторически различались по поведению для этих случаев и согласовывались во всех остальных.

 

14.7.5.10 Объекты Итераторы For-In

Итератор For-In — это объект, который представляет определенную итерацию над некоторым конкретным объектом. Объекты For-In Iterator никогда не доступны напрямую коду ECMAScript; они существуют исключительно для иллюстрации поведения EnumerateObjectProperties.

 

14.7.5.10.1 CreateForInIterator ( object )

Абстрактная операция CreateForInIterator принимает аргумент object (Object). Онf используется для создания объекта итератора For-In, который выполняет итерацию по собственным и унаследованным перечислимым строковым свойствам объекта object в определенном порядке. При вызове она выполняет следующие шаги:

1. Пусть итератор iterator будет ! OrdinaryObjectCreate(%ForInIteratorPrototype%, «[[Объект]], [[ObjectWasVisited]], [[VisitedKeys]], [[RemainingKeys]]»).
2. Установите iterator. [[Object]] на object.
3. Установите iterator. [[ObjectWasVisited]] значение false.
4. Установите iterator. [[VisitedKeys]] на новый пустой Список.
5. Установите iterator. [[RemainingKeys]] на новый пустой Список.
6. Вернуть iterator.

 

14.7.5.10.2 Объект %ForInIteratorPrototype%

Объект %ForInIteratorPrototype%:

  • имеет свойства, которые наследуются всеми объектами итераторами For-In.
  • это обычный объект.
  • имеет внутренний слот [[Prototype]], значение которого %IteratorPrototype%.
  • никогда не доступен напрямую для кода ECMAScript.
  • обладает следующими свойствами:
14.7.5.10.2.1 %ForInIteratorPrototype%.next ( )
1. Пусть O будет значением this.
2. Утверждено: Тип(O) - это объект.
3. Утверждено: O имеет все внутренние слоты экземпляра итератора For-In (14.7.5.10.3).
4. Пусть объект object будет O.[[Object]].
5. Пусть посещён visited равно O.[[VisitedKeys]].
6. Пусть осталось remaining равно O.[[RemainingKeys]].
7. Повторите,
   а. Если O.[[ObjectWasVisited]] является false (ложно), то
      i. Пусть ключи keys будут ? object.[[OwnPropertyKeys]]().
      ii. Для каждого элемента ключа key из ключей keys выполните
         1. Если Тип(key) - Строка, то
            а. Добавьте ключ key к оставшимся remaining.
      iii. Установите для O.[[ObjectWasVisited]] значение true.
   b. Повторять, пока remaining не пусто,
      i. Пусть r будет первым элементом из remaining.
      ii. Удалите первый элемент из remaining.
      iii. Если не существует элемента v из посещенного visited, такого что SameValue(r, v) является true (истинно), то
         1. Пусть desc будет ? object.[[GetOwnProperty]](r).
         2. Если desc не является undefined, тогда
            а. Добавьте r в список посещенных visited.
            b. Если desc.[[Enumerable]] является true (истинно), вернуть CreateIterResultObject(r, false).
c. Установить объект object на ? object.[[GetPrototypeOf]]().
d. Установите O.[[Object]] на object.
е. Установите O.[[ObjectWasVisited]] на значение false.
f. Если object имеет значение null, вернуть CreateIterResultObject(undefined, true).

 

14.7.5.10.3 Свойства экземпляров итератора For-In

Экземпляры итератора For-In — это обычные объекты, наследующие свойства от внутреннего объекта %ForInIteratorPrototype%. Экземпляры итератора For-In изначально создаются с внутренними слотами, перечисленными в Таблице 42.

Internal Slot (Внутренний слот) Description (Описание)
[[Object]] Значение объекта, свойства которого повторяются.
[[ObjectWasVisited]] Значение true, если итератор вызвал [[OwnPropertyKeys]] для [[Object]], в противном случае — false.
[[VisitedKeys]] Список значений String, которые были выданы этим итератором на данный момент.
[[RemainingKeys]] Список значений String, которые должны быть созданы для текущего объекта, до итерации свойств его прототипа (если его прототип не равен null)

Таблица 42: Внутренние слоты экземпляров итераторов For-In

 

14.8 Оператор continue

Синтаксис оператора continue

ContinueStatement [Yield, Await] :

continue ;

continue [не LineTerminator здесь] LabelIdentifier [?Yield, ?Await] ;

 

14.8.1 Статическая семантика: Ранние Ошибки

ContinueStatement :

continue ;

continue LabelIdentifier ;

  • Это синтаксическая ошибка, если этот ContinueStatement не вложен, прямо или косвенно (но не пересекает границы функции), в IterationStatement.

14.8.2 Семантика времени выполнения: Оценка

ContinueStatement : continue ;

1. Вернуть Completion { [[Type]]: continue, [[Value]]: empty, [[Target]]: empty }.

ContinueStatement : continue LabelIdentifier ;

1. Пусть label будет StringValue из LabelIdentifier.
2. Вернуть Completion { [[Type]]: continue, [[Value]]: empty, [[Target]]: label }.

 

14.9 Оператор break

Синтаксис оператора break

BreakStatement [Yield, Await] :

break ;

break [не LineTerminator здесь] LabelIdentifier [?Yield, ?Await] ;

 

14.9.1 Статическая семантика: ранние ошибки

BreakStatement : break ;

  • Это синтаксическая ошибка, если этот BreakStatement не вложен, прямо или косвенно (но не пересекает границы функции), в IterationStatement или SwitchStatement.

14.9.2 Семантика времени выполнения: оценка

BreakStatement : break ;

1. Вернуть Completion { [[Type]]: break, [[Value]]: empty, [[Target]]: empty }.

BreakStatement : break LabelIdentifier ;

1. Пусть label будет StringValue из LabelIdentifier.
2. Вернуть Completion { [[Type]]: break, [[Value]]: empty, [[Target]]: label}.

 

14.10 Оператор return

Синтаксис оператора return

ReturnStatement [Yield, Await] :

return ;

return [не LineTerminator здесь] Expression [+In, ?Yield, ?Await] ;

 

Примечание

Оператор return заставляет функцию прекращать выполнение и, в большинстве случаев, возвращает значение вызывающей стороне. Если выражение Expression не указано, возвращаемое значение является undefined (не определено). В противном случае возвращаемое значение является значением Expression. Оператор return может не возвращать значение вызывающей стороне в зависимости от окружающего контекста. Например, в блоке try запись завершения оператора return может быть заменена другой записью завершения во время оценки блока finally.

14.10.1 Семантика времени выполнения: оценка

ReturnStatement : return ;

1. Вернуть Completion { [[Type]]: return, [[Value]]: undefined, [[Target]]: empty }.

ReturnStatement : return Expression ;

1. Пусть exprRef будет результатом вычисления Expression. 
2. Пусть exprValue будет ? GetValue(exprRef). 
3. Если ! GetGeneratorKind() является async, установить exprValue на ? Await(exprValue). 
4. Вернуть Completion { [[Type]]: return, [[Value]]: exprValue, [[Target]]: empty }.

 

14.11 Оператор with

Синтаксис оператора with

WithStatement [Yield, Await, Return] :

with ( Expression [+In, ?Yield, ?Await] ) Statement [?Yield, ?Await, ?Return]

Примечание

Оператор with добавляет объект Environment Record для вычисляемого объекта в лексическую среду текущего контекста выполнения. Затем он выполняет инструкцию, используя эту расширенную лексическую среду. Наконец, восстанавливается исходная лексическая среда.

 

14.11.1 Статическая семантика: Ранние Ошибки

WithStatement : with ( Expression ) Statement

  • Это синтаксическая ошибка, если код, соответствующий этому производству, содержится в коде строгого режима.
  • Это синтаксическая ошибка, если IsLabelledFunction(Statement) является true (истинно).
Примечание

Второе правило необходимо применять только в том случае, если реализовано расширение, указанное в разделе B.3.1.

 

14.11.2 Семантика времени выполнения: Оценка

WithStatement : with ( Expression ) Statement

1. Пусть val будет результатом вычисления выражения Expression.
2. Пусть obj будет ? ToObject(? GetValue(val)).
3. Пусть oldEnv будет LexicalEnvironment текущего контекста выполнения.
4. Пусть newEnv будет NewObjectEnvironment(obj, true, oldEnv).
5. Установите для LexicalEnvironment текущего контекста выполнения значение newEnv.
6. Пусть C будет результатом оценки Statement.
7. Установите LexicalEnvironment текущего контекста выполнения на oldEnv.
8. Вернуть Завершение(UpdateEmpty (C, undefined)).
Примечание

Независимо от того, как управление покидает внедренный оператор Statement, обычно или в результате какой-либо формы внезапного завершения или исключения, LexicalEnvironment всегда возвращается в свое прежнее состояние.

 

14.12 Оператор switch

Синтаксис оператора switch

SwitchStatement [Yield, Await, Return] :

switch ( Expression [+In, ?Yield, ?Await] ) CaseBlock [?Yield, ?Await, ?Return]

CaseBlock [Yield, Await, Return] :

{ CaseClauses [?Yield, ?Await, ?Return] opt }

{ CaseClauses [?Yield, ?Await, ?Return] opt DefaultClause [?Yield, ?Await, ?Return] CaseClauses [?Yield, ?Await, ?Return] opt }

CaseClauses [Yield, Await, Return] :

CaseClause [?Yield, ?Await, ?Return]

CaseClauses [?Yield, ?Await, ?Return] CaseClause [?Yield, ?Await, ?Return]

CaseClause [Yield, Await, Return] :

case Expression [+In, ?Yield, ?Await] : StatementList [?Yield, ?Await, ?Return] opt

DefaultClause [Yield, Await, Return] :

default : StatementList [?Yield, ?Await, ?Return] opt

 

14.12.1 Статическая семантика: ранние ошибки

SwitchStatement : switch ( Expression ) CaseBlock

 

14.12.2 Семантика времени выполнения: Оценка Блока Случая — CaseBlockEvaluation

С параметром input.

CaseBlock : { }

1. Вернуть NormalCompletion(undefined).

CaseBlock : { CaseClauses }

1. Пусть V будет undefined.
2. Пусть A будет Списком элементов CaseClause в CaseClauses в порядке исходного текста.
3. Пусть found (найденное) будет false.
4. Для каждого CaseClause C из A выполните
  а. Если found является false, то
    i. Установить found на ? CaseClauseIsSelected(C, input).
  b. Если found является true, то
    i. Пусть R будет результатом вычисления C.
    ii. Если R.[[Value]] не empty, установите V равным R.[[Value]].
    iii. Если R - внезапное завершение, верните завершение Completion(UpdateEmpty(R, V)).
5. Верните нормальное завершение NormalCompletion(V).

CaseBlock : { CaseClauses opt DefaultClause CaseClauses opt }

1. Пусть V будет undefined.
2. Если присутствует первый CaseClauses, то
  а. Пусть A будет Списком элементов CaseClause в первых CaseClauses в порядке исходного текста.
3. Иначе,
  а. Пусть A будет «».
4. Пусть found (найденное) будет false.
5. Для каждого CaseClause C из A выполните
  а. Если found является false, то
    i. Установить found на ? CaseClauseIsSelected(C, input).
  b. Если found является true, то
    i. Пусть R будет результатом вычисления C.
    ii. Если R.[[Value]] не empty, установите V равным R.[[Value]].
    iii. Если R - внезапное завершение, верните завершение Completion(UpdateEmpty(R, V)).
6. Пусть foundInB имеет значение false.
7. Если присутствует второй CaseClauses, то
  а. Пусть B будет списком элементов CaseClause во втором CaseClauses в порядке исходного текста.
8. Иначе,
  а. Пусть B будет «».
9. Если found является false, то
  а. Для каждого CaseClause C из B выполните
    i. Если foundInB является false, то
      1. Установите для foundInB значение ? CaseClauseIsSelected(C, input).
    ii. Если foundInB является true, то
      1. Пусть R будет результатом вычисления CaseClause C.
      2. Если R.[[Value]] не empty, установите V равным R.[[Value]].
      3. Если R - внезапное завершение, верните завершение Completion(UpdateEmpty(R, V)).
10. Если foundInB является true, вернуть NormalCompletion(V).
11. Пусть R будет результатом вычисления DefaultClause.
12. Если R.[[Value]] не empty, установите V равным R.[[Value]].
13. Если R - внезапное завершение, верните завершение Completion(UpdateEmpty(R, V)).
14. ПРИМЕЧАНИЕ. Ниже приводится еще одна полная итерация второго CaseClauses.
15. Для каждого CaseClause C из B выполните:
  а. Пусть R будет результатом вычисления CaseClause C.
  b. Если R.[[Value]] не empty, установите V равным R.[[Value]].
  c. Если R - внезапное завершение, верните завершение Completion(UpdateEmpty(R, V)).
16. Вернуть нормальное завершение NormalCompletion(V).

 

14.12.3 CaseClauseIsSelected ( C, input )

Абстрактная операция CaseClauseIsSelected принимает аргументы C (узел синтаксического анализа CaseClause) и input (значение языка ECMAScript). Он определяет, соответствует ли C вводу input. При вызове она выполняет следующие шаги:

1. Утверждено: C является экземпляром производства CaseClause : case Expression : StatementList opt.
2. Пусть exprRef будет результатом оценки выражения Expression из C.
3. Пусть clauseSelector будет ? GetValue(exprRef).
4. Верните IsStrictlyEqual(input, clauseSelector).
Примечание

Эта операция не выполняет C из StatementList (если есть). Алгоритм CaseBlock использует свое возвращаемое значение, чтобы определить, какой StatementList должен начать выполнение.

 

14.12.4 Семантика времени выполнения: Оценка

SwitchStatement : switch ( Expression ) CaseBlock

1. Пусть exprRef будет результатом вычисления Expression.
2. Пусть switchValue будет ? GetValue(exprRef).
3. Пусть oldEnv будет LexicalEnvironment текущего контекста выполнения.
4. Пусть blockEnv будет NewDeclarativeEnvironment(oldEnv).
5. Выполните создание экземпляра объявления блока BlockDeclarationInstantiation(CaseBlock, blockEnv).
6. Установите для LexicalEnvironment текущего контекста выполнения значение blockEnv.
7. Пусть R будет CaseBlockEvaluation из CaseBlock с аргументом switchValue.
8. Установите LexicalEnvironment текущего контекста выполнения на oldEnv.
9. Верните R.
Примечание

Независимо от того, как управление покидает SwitchStatement, LexicalEnvironment всегда возвращается в свое прежнее состояние.

CaseClause : case Expression :

1. Верните NormalCompletion(empty).

CaseClause : case Expression : StatementList

1. Верните результат вычисления StatementList.

DefaultClause : default :

1. Верните NormalCompletion(empty).

DefaultClause : default : StatementList

1. Верните результат вычисления StatementList.

 

14.13 Помеченные операторы

Синтаксис помеченных операторов

LabelledStatement [Yield, Await, Return] :

LabelIdentifier [?Yield, ?Await] : LabelledItem [?Yield, ?Await, ?Return]

LabelledItem [Yield, Await, Return] :

Statement [?Yield, ?Await, ?Return]

FunctionDeclaration [?Yield, ?Await, ~Default]

 

Примечание

Заявление Statement может быть предварено меткой. Помеченные операторы используются только вместе с помеченными операторами break и continue. В ECMAScript нет оператора goto. Заявление Statement может быть частью LabelledStatement, который сам может быть частью LabelledStatement и т. д. Введённые таким образом метки вместе называются «текущим набором меток» (current label set) при описании семантики отдельных операторов.

 

14.13.1 Статическая семантика: ранние ошибки

LabelledItem : FunctionDeclaration

  • Если какой-либо исходный текст соответствует этому правилу, это является синтаксической ошибкой.
Примечание

Альтернативное определение этого правила приведено в разделе B.3.1.

 

14.13.2 Статическая семантика: IsLabelledFunction ( stmt )

Абстрактная операция IsLabelledFunction (Является Ли Помеченным Оператором) принимает аргумент stmt. При вызове она выполняет следующие шаги:

1. Если stmt не является LabelledStatement, верните false.
2. Пусть item будет LabelledItem для stmt.
3. Если item является LabelledItem : FunctionDeclaration, верните true.
4. Пусть subStmt будет выражением Statement элемента item.
5. Верните IsLabelledFunction(subStmt).

 

14.13.3 Семантика времени выполнения: оценка

LabelledStatement : LabelIdentifier : LabelledItem

1. Пусть newLabelSet будет новым пустым Списком.
2. Верните LabelledEvaluation этого LabelledStatement с аргументом newLabelSet.

 

14.13.4 Семантика времени выполнения: LabelledEvaluation

С параметром labelSet.

BreakableStatement : IterationStatement

1. Пусть stmtResult будет LoopEvaluation для IterationStatement с аргументом labelSet.
2. Если stmtResult.[[Type]] является break, то
  а. Если stmtResult.[[Target]] является empty, то
    i. Если stmtResult.[[Value]] является empty, установите для stmtResult значение NormalCompletion(undefined).
    ii. В противном случае установите для stmtResult значение NormalCompletion(stmtResult.[[Value]]).
3. Вернуть завершение Completion(stmtResult).

BreakableStatement : SwitchStatement

1. Пусть stmtResult будет результатом вычисления SwitchStatement.
2. Если stmtResult.[[Type]] является break, то
  а. Если stmtResult.[[Target]] является empty, то
    i. Если stmtResult.[[Value]] является empty, установите для stmtResult значение NormalCompletion(undefined).
    ii. В противном случае установите для stmtResult значение NormalCompletion(stmtResult.[[Value]]).
3. Вернуть завершение Completion(stmtResult).
Примечание 1

BreakableStatement — это оператор, из которого можно выйти с помощью безымянного BreakStatement.

LabelledStatement : LabelIdentifier : LabelledItem

1. Пусть label будет строковым значением StringValue для LabelIdentifier.
2. Пусть newLabelSet будет конкатенацией списка labelSet и «label».
3. Пусть stmtResult будет LabelledEvaluation для LabelledItem с аргументом newLabelSet.
4. Если stmtResult.[[Type]] является break, а SameValue(stmtResult.[[Target]], label) является true, то
  а. Установите для stmtResult значение NormalCompletion(stmtResult.[[Value]]).
5. Вернуть Завершение Completion(stmtResult).

LabelledItem : FunctionDeclaration

1. Верните результат вычисления FunctionDeclaration.

Statement :

BlockStatement

VariableStatement

EmptyStatement

ExpressionStatement

IfStatement

ContinueStatement

BreakStatement

ReturnStatement

WithStatement

ThrowStatement

TryStatement

DebuggerStatement

1. Верните результат оценки Statement.
Примечание 2

Только два производства заявления Statement, которые имеют особую семантику для LabelledEvaluation, — это BreakableStatement и LabelledStatement.

 

14.14 Оператор throw

Синтаксис оператора throw

ThrowStatement [Yield, Await] :

throw [нет LineTerminator здесь] Expression [+In, ?Yield, ?Await] ;

 

14.14.1 Семантика времени выполнения: Оценка

ThrowStatement : throw Expression ;

1. Пусть exprRef будет результатом вычисления выражения Expression.
2. Пусть exprValue будет ? GetValue(exprRef).
3. Вернуть ThrowCompletion(exprValue).

 

14.15 Оператор try

Синтаксис оператора try

TryStatement [Yield, Await, Return] :

try Block [?Yield, ?Await, ?Return] Catch [?Yield, ?Await, ?Return]

try Block [?Yield, ?Await, ?Return] Finally [?Yield, ?Await, ?Return]

try Block [?Yield, ?Await, ?Return] Catch [?Yield, ?Await, ?Return] Finally [?Yield, ?Await, ?Return]

Catch [Yield, Await, Return] :

catch ( CatchParameter [?Yield, ?Await] ) Block [?Yield, ?Await, ?Return]

catch Block [?Yield, ?Await, ?Return]

Finally [Yield, Await, Return] :

finally Block [?Yield, ?Await, ?Return]

CatchParameter [Yield, Await] :

BindingIdentifier [?Yield, ?Await]

BindingPattern [?Yield, ?Await]

Примечание

Оператор try включает в себя блок кода, в котором может возникнуть исключительное условие, например ошибка времени выполнения или оператор throw. Предложение catch предоставляет код обработки исключений. Когда предложение catch перехватывает исключение, его CatchParameter привязывается к этому исключению.

14.15.1 Статическая семантика: Ранние Ошибки

Catch : catch ( CatchParameter ) Block

  • Это синтаксическая ошибка, если BoundNames из CatchParameter содержит какие-либо повторяющиеся элементы.
  • Это синтаксическая ошибка, если какой-либо элемент BoundNames из CatchParameter также встречается в LexicallyDeclaredNames из Block.
  • Это синтаксическая ошибка, если какой-либо элемент BoundNames из CatchParameter также встречается в VarDeclaredNames из Block.
Примечание

Альтернативная статическая семантика для этой продукции приведена в приложении B.3.4.

 

14.15.2 Семантика времени выполнения: CatchClauseEvaluation

С параметром брошенного значения thrownValue.

Catch : catch ( CatchParameter ) Block

1. Пусть oldEnv будет LexicalEnvironment текущего контекста выполнения.
2. Пусть catchEnv будет NewDeclarativeEnvironment(oldEnv).
3. Для каждого элемента argName из BoundNames параметра CatchParameter выполните
  а. Выполнять ! catchEnv.CreateMutableBinding(argNamefalse).
4. Задайте для LexicalEnvironment текущего контекста выполнения значение catchEnv.
5. Пусть status будет BindingInitialization из CatchParameter с аргументами thrownValue и catchEnv.
6. Если status - внезапное завершение, то
  а. Установите для LexicalEnvironment текущего контекста выполнения значение oldEnv.
  b. Верните Завершение Completion(status).
7. Пусть B будет результатом вычисления блока.
8. Установите LexicalEnvironment текущего контекста выполнения на oldEnv.
9. Верните завершение (B).

Catch : catch Block

1. Верните результат оценки Block.
Примечание

Независимо от того, как контроль покидает Block, LexicalEnvironment всегда возвращается в свое прежнее состояние.

 

14.15.3 Семантика времени выполнения: Оценка

TryStatement : try Block Catch

1. Пусть B будет результатом оценки Block.
2. Если B.[[Type]] является throw, пусть C будет CatchClauseEvaluation для Catch с аргументом B.[[Value]].
3. Иначе, пусть C будет B.
4. Вернуть Завершение Completion(UpdateEmpty(C, undefined)).

TryStatement : try Block Finally

1. Пусть B будет результатом оценки Block.
2. Пусть F будет результатом вычисления Finally.
3. Если F.[[Type]] является normal, установите F на B.
4. Вернуть Завершение Completion(UpdateEmpty(F, undefined)).

TryStatement : try Block Catch Finally

1. Пусть B будет результатом оценки Block.
2. Если B.[[Type]] является throw, пусть C будет CatchClauseEvaluation для Catch с аргументом B.[[Value]].
3. Иначе, пусть C будет B.
4. Пусть F будет результатом вычисления Finally.
5. Если F.[[Type]] является normal, установите F на C.
6. Вернуть Завершение Completion(UpdateEmpty(F, undefined)).

 

14.16 Оператор debugger

Синтаксис оператора debugger

DebuggerStatement :

debugger ;

 

14.16.1 Семантика времени выполнения: Оценка

Примечание

Оценка DebuggerStatement может позволить реализации вызвать точку останова при запуске под отладчиком. Если отладчик отсутствует или активен, этот оператор не имеет видимого эффекта.

DebuggerStatement : debugger ;

1. Если средство отладки, определяемое реализацией, доступно и включено, то
  а. Выполните действие отладки, определяемое реализацией.
  b. Пусть result будет значением завершения, определяемым реализацией.
2. Иначе,
  а. Пусть result будет NormalCompletion(empty).
3. Вернуть result.

 

 

Информационные ссылки

Стандарт ECMAScript — Раздел «14 ECMAScript Language: Statements and Declarations» — https://tc39.es/ecma262/#sec-ecmascript-language-statements-and-declarations