JavaScript | Оператор for

JavaScript | Оператор for

 

Оператор for входит в раздел «операторов итерации» (Iteration Statements) стандарта ECMAScript.

 

Синтаксис оператора 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]

 

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

ForStatement :

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

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

for ( LexicalDeclaration Expression opt ; Expression opt ) Statement

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

 

Примечание

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

 

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

Синтаксическая ошибка, если какой-либо элемент BoundNames из LexicalDeclaration также встречается в VarDeclaredNames из Statement.

 

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

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

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

1. Если первое выражение присутствует, то
   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).

 

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).

 

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.

 

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

JavaScript | Алгоритмические обозначения

JavaScript | Условные обозначения

JavaScript | Зарезервированные слова (ReservedWord)

Стандарт ECMAScript — Раздел «14.7.4 The for Statement» — https://tc39.es/ecma262/#sec-for-statement