Спецификация ECMAScript 5.1 с аннотациями

Поделиться

12 Инструкции #

Синтаксис

Statement :

Block
VariableStatement
EmptyStatement
ExpressionStatement
IfStatement
IterationStatement
ContinueStatement
BreakStatement
ReturnStatement
WithStatement
LabelledStatement
SwitchStatement
ThrowStatement
TryStatement
DebuggerStatement

Семантика

Statement Инструкция может являться частью LabelledStatement Инструкция с меткой, которая, в свою очередь, может быть частью другой LabelledStatement, и так далее. При описании семантики отдельных инструкций подобные метки собирательно называются "текущим набором меток". LabelledStatement не имеет иного семантического значения, кроме внесения метки в набор меток. Набор меток для IterationStatement Инструкция итерации или SwitchStatement Инструкция switch изначально содержит единственный элемент empty пусто. Набор меток для любой другой инструкции изначально пуст.

ПРИМЕЧАНИЕ Известно, что несколько широко распространённых реализаций языка ECMAScript поддерживают использование FunctionDeclaration Объявление функции в качестве инструкции. Однако в семантике, применимой к таким объявлениям функций, имеются существенные противоречивые вариации реализаций. Из-за этих противоречий код, написанный с использованием FunctionDeclaration в качестве Statement, не является надёжным при переносе из одной реализации в другую. Поэтому для реализаций ECMAScript рекомендуется либо отключать использование FunctionDeclaration, либо генерировать предупреждение в случае такого использования. Возможно, в последующих версиях языка ECMAScript появятся альтернативные средства для переноса кода, позволяющие объявлять функции в контексте Statement.

12.1 Блок #

Синтаксис

Block :

{ StatementListopt}

StatementList :

Statement
StatementList Statement

Семантика

Для вычисления Block : { } выполняются следующие шаги:

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

Для вычисления Block : { StatementList } выполняются следующие шаги:

  1. Вернуть результат вычисления StatementList Список инструкций.

Для вычисления StatementList : Statement выполняются следующие шаги:

  1. Пусть s будет результатом вычисления Statement.

  2. Если было сгенерировано исключение, вернуть (throw, V, empty), где V – исключение. (После этого продолжается выполнение кода, как если бы исключение не было сгенерировано).

  3. Вернуть s.

Для вычисления StatementList : StatementList Statement выполняются следующие шаги:

  1. Пусть sl будет результатом вычисления StatementList.

  2. Если slнепредвиденное завершение, вернуть sl.

  3. Пусть s будет результатом вычисления Statement.

  4. Если было сгенерировано исключение, вернуть (throw, V, empty), где V – исключение. (После этого продолжается выполнение кода, как если бы исключение не было сгенерировано).

  5. Если s.value – пусто, пусть V = sl.value, в противном случае пусть V = s.value.

  6. Вернуть (s.type, V, s.target).

12.2 Инструкция переменной #

Синтаксис

VariableStatement :

var VariableDeclarationList ;

VariableDeclarationList :

VariableDeclaration
VariableDeclarationList
, VariableDeclaration

VariableDeclarationListNoIn :

VariableDeclarationNoIn
VariableDeclarationListNoIn
, VariableDeclarationNoIn

VariableDeclaration :

Identifier Initialiseropt

VariableDeclarationNoIn :

Identifier InitialiserNoInopt

Initialiser :

= AssignmentExpression

InitialiserNoIn :

= AssignmentExpressionNoIn

Инструкция переменной объявляет переменные, создаваемые в соответствии с определением в пункте 10.5. При создании переменные инициализируются со значением undefined. Переменной с инициализатором Initialiser присваивается значение его выражения присваивания AssignmentExpression не в момент создания переменной, а в момент исполнения инструкции переменой VariableStatement.

Семантика

Для вычисления VariableStatement : var VariableDeclarationList ; выполняются следующие шаги:

  1. Вычислить VariableDeclarationList Список объявления переменных.

  2. Вернуть (normal, empty, empty).

Для вычисления VariableDeclarationList : VariableDeclaration выполняются следующие шаги:

  1. Вычислить VariableDeclaration Объявление переменной.

Для вычисления VariableDeclarationList : VariableDeclarationList , VariableDeclaration выполняются следующие шаги:

  1. Вычислить VariableDeclarationList.

  2. Вычислить VariableDeclaration.

Для вычисления VariableDeclaration : Identifier выполняются следующие шаги:

  1. Вернуть строковое значение, содержащее такую же последовательность символов, что и в Identifier.

Для вычисления VariableDeclaration : Identifier Initialiser выполняются следующие шаги:

  1. Пусть lhs будет результатом вычисления Identifier в соответствии с описанием в пункте 11.1.2.

  2. Пусть rhs будет результатом вычисления Initialiser Инициализатор.

  3. Пусть value будет GetValue(rhs).

  4. Вызвать PutValue(lhs, value).

  5. Вернуть строковое значение, содержащее такую же последовательность символов, что и в Identifier.

ПРИМЕЧАНИЕ Строковое значение VariableDeclaration используется при вычислении инструкций for-in (12.6.4).

Если VariableDeclaration вложено в инструкцию with, а идентификатор в VariableDeclaration такой же, что и имя свойства объекта привязки для записи окружения объекта инструкции with, то в шаге 4 будет присваиваться значение свойству, а не привязке VariableEnvironment для Identifier.

Для вычисления Initialiser : = AssignmentExpression выполняются следующие шаги:

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

Для вычисления VariableDeclarationListNoIn Список объявления переменных без in, VariableDeclarationNoIn Объявление переменной без in и InitialiserNoIn Инициализатор без in выполняются точно такие же шаги, что и для вычисления VariableDeclarationList, VariableDeclaration и Initialiser, за исключением того, что вместо вложенных VariableDeclarationList, VariableDeclaration, Initialiser и AssignmentExpression вычисляются вложенные VariableDeclarationListNoIn, VariableDeclarationNoIn, InitialiserNoIn и AssignmentExpressionNoIn соответственно.

12.2.1 Ограничения строгого режима #

Если VariableDeclaration или VariableDeclarationNoIn встречается в строгом коде, и при этом его идентификатор Identifier представляет собой либо "eval", либо "arguments", генерируется SyntaxError.

12.3 Пустая инструкция #

Синтаксис

EmptyStatement :

;

Семантика

Для вычисления EmptyStatement : ; выполняются следующие шаги:

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

12.4 Инструкция-выражение #

Синтаксис

ExpressionStatement :

[lookahead {{,function}] Expression ;

ПРИМЕЧАНИЕ ExpressionStatement Инструкция-выражение не может начинаться с открывающей фигурной скобки, поскольку из-за этого её можно перепутать с блоком Block. Кроме того, она не может начинаться с ключевого слова function, так как из-за этого её можно перепутать с объявлением функции FunctionDeclaration.

Семантика

Для вычисления ExpressionStatement : [lookahead {{,function}]Expression; выполняются следующие шаги:

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

  2. Вернуть (normal, GetValue(exprRef), empty).

12.5 Инструкция if #

Синтаксис

IfStatement :

if ( Expression ) Statement else Statement
if ( Expression ) Statement

Каждое else, для которого выбор соответствующего ему if является неоднозначным, будет ассоциироваться с ближайшим к нему if, у которого в противном случае нет соответствующего ему else.

Семантика

Для вычисления IfStatement : if ( Expression ) Statement else Statement выполняются следующие шаги:

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

  2. Если ToBoolean(GetValue(exprRef)) равно true, то

    1. Вернуть результат вычисления первого Statement.

  3. Иначе

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

Для вычисления IfStatement : if ( Expression ) Statement выполняются следующие шаги:

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

  2. Если ToBoolean(GetValue(exprRef)) равно false, вернуть (normal, empty, empty).

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

12.6 Инструкции итерации #

Синтаксис

IterationStatement :

do Statement while ( Expression );
while ( Expression ) Statement
for ( ExpressionNoInopt; Expressionopt; Expressionopt) Statement
for ( var VariableDeclarationListNoIn; Expressionopt; Expressionopt) Statement
for ( LeftHandSideExpression in Expression ) Statement
for ( var VariableDeclarationNoIn in Expression ) Statement

12.6.1 Инструкция do-while #

Для вычисления do Statement while ( Expression ); выполняются следующие шаги:

  1. Пусть V = empty пусто.

  2. Пусть iterating итерация будет true.

  3. Повторять, пока iterating равно true.

    1. Пусть stmt будет результатом вычисления Statement.

    2. Если stmt.value не равно empty, пусть V = stmt.value.

    3. Если stmt.type не равно continue || stmt.target не принадлежит к текущему набору меток, то

      1. Если stmt.type не равно break, и stmt.target принадлежит к текущему набору меток, вернуть (normal, V, empty).

      2. Если stmtнепредвиденное завершение, вернуть stmt.

    4. Пусть exprRef будет результатом вычисления Expression.

    5. Если ToBoolean(GetValue(exprRef)) равно false, присвоить iterating значение false.

  4. Вернуть (normal, V, empty);

12.6.2 Инструкция while #

Для вычисления IterationStatement : while ( Expression ) Statement выполняются следующие шаги:

  1. Пусть V = empty.

  2. Повторить

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

    2. Если ToBoolean(GetValue(exprRef)) равно false, вернуть (normal, V, empty).

    3. Пусть stmt будет результатом вычисления Statement.

    4. Если stmt.value не равно empty, пусть V = stmt.value.

    5. Если stmt.type не равно continue || stmt.target не принадлежит к текущему набору меток, то

      1. Если stmt.type равно break, и stmt.target принадлежит к текущему набору меток, то

        1. Вернуть (normal, V, empty).

      2. Если stmtнепредвиденное завершение, вернуть stmt.

12.6.3 Инструкция for #

Для вычисления
IterationStatement : for ( ExpressionNoInopt; Expressionopt; Expressionopt) Statement
выполняются следующие шаги:

  1. Если присутствует ExpressionNoIn, то

    1. Пусть exprRef будет результатом вычисления ExpressionNoIn.

    2. Вызвать GetValue(exprRef). (Это значение не используется).

  2. Пусть V = empty.

  3. Повторить

    1. Если присутствует первое Expression, то

      1. Пусть testExprRef будет результатом вычисления первого Expression.

      2. Если ToBoolean(GetValue(testExprRef)) равно false, вернуть (normal, V, empty).

    2. Пусть stmt будет результатом вычисления Statement.

    3. Если stmt.value не равно empty, пусть V = stmt.value.

    4. Если stmt.type не равно break, и stmt.target принадлежит к текущему набору меток, вернуть (normal, V, empty).

    5. Если stmt.type не равно continue || stmt.target не принадлежит к текущему набору меток, то

      1. Если stmtнепредвиденное завершение, вернуть stmt.

    6. Если присутствует второе Expression, то

      1. Пусть incExprRef будет результатом вычисления второго Expression.

      2. Вызвать GetValue(incExprRef). (Это значение не используется.)

Для вычисления
IterationStatement : for ( var VariableDeclarationListNoIn ; Expressionopt; Expressionopt) Statement
выполняются следующие шаги:

  1. Вычислить VariableDeclarationListNoIn.

  2. Пусть V = empty.

  3. Повторить

    1. Если присутствует первое Expression, то

      1. Пусть testExprRef будет результатом вычисления первого Expression.

      2. Если ToBoolean(GetValue(testExprRef)) равно false, вернуть (normal, V, empty).

    2. Пусть stmt будет результатом вычисления Statement.

    3. Если stmt.value не равно empty, пусть V = stmt.value.

    4. Если stmt.type не равно break, и stmt.target принадлежит к текущему набору меток, вернуть (normal, V, empty).

    5. Если stmt.type не равно continue || stmt.target не принадлежит к текущему набору меток, то

      1. Если stmtнепредвиденное завершение, вернуть stmt.

    6. Если присутствует второе Expression, то

      1. Пусть incExprRef будет результатом вычисления второго Expression.

      2. Вызвать GetValue(incExprRef). (Это значение не используется.)

12.6.4 Инструкция for-in #

Для вычисления IterationStatement : for (LeftHandSideExpression in Expression ) Statement выполняются следующие шаги:

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

  2. Пусть experValue будет GetValue(exprRef).

  3. Если experValue равно null или undefined, вернуть (normal, empty, empty).

  4. Пусть obj будет ToObject(experValue).

  5. Пусть V = empty.

  6. Повторить

    1. Пусть P будет именем следующего свойства для obj, у которого атрибут [[Enumerable]] равен true. Если такого свойства нет, вернуть (normal, V, empty).

    2. Пусть lhsRef будет результатом вычисления LeftHandSideExpression (это значение можно вычислять неоднократно).

    3. Вызвать PutValue(lhsRef, P).

    4. Пусть stmt будет результатом вычисления Statement.

    5. Если stmt.value не равно empty, пусть V = stmt.value.

    6. Если stmt.type не равно break, и stmt.target принадлежит к текущему набору меток, вернуть (normal, V, empty).

    7. Если stmt.type не равно continue || stmt.target не принадлежит к текущему набору меток, то

      1. Если stmtнепредвиденное завершение, вернуть stmt.

Для вычисления
IterationStatement : for ( var VariableDeclarationNoIn in Expression ) Statement
выполняются следующие шаги:

  1. Пусть varName будет результатом вычисления VariableDeclarationNoIn.

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

  3. Пусть experValue будет GetValue(exprRef).

  4. Если experValue равно null или undefined, вернуть (normal, empty, empty).

  5. Пусть obj будет ToObject(experValue).

  6. Пусть V = empty.

  7. Повторить

    1. Пусть P будет именем следующего свойства для obj, у которого атрибут [[Enumerable]] равен true. Если такого свойства нет, вернуть (normal, V, empty).

    2. Пусть значение varRef будет результатом вычисления varName, как если бы имела место ссылка на идентификатор (11.1.2). Это значение можно вычислять неоднократно.

    3. Вызвать PutValue(varRef, P).

    4. Пусть stmt будет результатом вычисления Statement.

    5. Если stmt.value не равно empty, пусть V = stmt.value.

    6. Если stmt.type не равно break, и stmt.target принадлежит к текущему набору меток, вернуть (normal, V, empty).

    7. Если stmt.type не равно continue || stmt.target не принадлежит к текущему набору меток, то

      1. Если stmtнепредвиденное завершение, вернуть stmt.

Механизм и порядок перечисления свойств (шаг 6.a в первом алгоритме и шаг 7.a во втором алгоритме) не указан. Свойства перечисляемого объекта могут быть удалены во время перечисления. Если свойство, ещё не посещённое при перечислении, удаляется, то оно не будет посещено. Если во время перечисления к объекту добавляются новые свойства, их посещение в процессе текущего перечисления не гарантируется. Одно имя свойства нельзя посетить более одного раза во время перечисления.

Перечисление свойств объекта включает в себя перечисление свойств его прототипа, а также прототипа этого прототипа, и так далее рекурсивно. Однако свойство прототипа не будет перечисляться, если оно "находится в тени" какого-либо предыдущего объекта в цепочке прототипов, который имеет свойство с таким же именем. Чтобы определить, находится ли свойство объекта-прототипа в тени предыдущего объекта в цепочке прототипов, значения атрибутов [[Enumerable]] не учитываются.

ПРИМЕЧАНИЕ См. Примечание к пункту 11.13.1.

12.7 Инструкция continue #

Синтаксис

ContinueStatement :

continue ;

continue [no LineTerminator here] Identifier;

Семантика

Программа будет считаться синтаксически некорректной, если выполняется одно из следующих условий:

Для вычисления ContinueStatement Инструкция continue без идентификатора Identifier выполняются следующие шаги:

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

Для вычисления ContinueStatement с необязательным Identifier выполняются следующие шаги:

  1. Вернуть (continue, empty, Identifier).

12.8 Инструкция break #

Синтаксис

BreakStatement :

break ;

break [no LineTerminator here] Identifier ;

Семантика

Программа будет считаться синтаксически некорректной, если выполняется одно из следующих условий:

Для вычисления BreakStatement Инструкция break без идентификатора Identifier выполняются следующие шаги:

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

Для вычисления BreakStatement Инструкция break с идентификатором Identifier выполняются следующие шаги:

  1. Вернуть (break, empty, Identifier).

12.9 Инструкция return #

Синтаксис

ReturnStatement :

return ;

return [no LineTerminator here] Expression ;

Семантика

Программа на ECMAScript считается синтаксически некорректной, если она содержит инструкцию return, которая не является частью тела функции FunctionBody. Инструкция return заставляет функцию прекратить выполнение и вернуть в вызывающую программу значение. Если выражение Expression пропущено, возвращается значение undefined. В противном случае возвращается значение выражения Expression.

Для вычисления ReturnStatement : return [no LineTerminator here] Expressionopt; выполняются следующие шаги:

  1. Если Expression отсутствует, вернуть (return, undefined, empty).

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

  3. Вернуть (return, GetValue(exprRef), empty).

12.10 Инструкция with #

Синтаксис

WithStatement :

with ( Expression ) Statement

Инструкция with добавляет запись окружения вычисляемого объекта к Лексическому Окружению текущего контекста исполнения. Затем инструкция исполняется с использованием этого приращённого Лексического Окружения. И, наконец, восстанавливается оригинальное Лексическое Окружение.

Семантика

Для вычисления WithStatement : with ( Expression ) Statement выполняются следующие шаги:

  1. Пусть val будет результатом вычисления Expression.

  2. Пусть obj будет ToObject(GetValue(val)).

  3. Пусть oldEnv будет Лексическим Окружением активного контекста исполнения.

  4. Пусть newEnv будует результатом вызова NewObjectEnvironment с передачей в качестве аргументов obj и oldEnv.

  5. Присвоить флагу provideThis для newEnv значение true.

  6. Присвоить LexicalEnvironment текущего контекста исполнения значение newEnv.

  7. Пусть C будет результатом вычисления инструкции Statement, но если при вычислении генерируется исключение, то пусть C будет (throw, V, empty), где V – исключение. (После этого продолжается выполнение кода, как если бы исключение не было сгенерировано).

  8. Присвоить LexicalEnvironment текущего контекста исполнения значение oldEnv.

  9. Вернуть C.

ПРИМЕЧАНИЕ Независимо от того, каким образом управление выходит из вложенной инструкции Statement (то ли обычным способом, то ли в результате непредвиденного завершения или исключения), лексическое окружение LexicalEnvironment всегда восстанавливается до своего начального состояния.

12.10.1 Ограничения строгого режима #

Код в строгом режиме не может содержать инструкцию with. Наличие WithStatement в контексте строгого режима интерпретируется как SyntaxError.

12.11 Инструкция switch #

Синтаксис

SwitchStatement :

switch ( Expression ) CaseBlock

CaseBlock :

{ CaseClausesopt}
{ CaseClausesoptDefaultClause CaseClausesopt}

CaseClauses :

CaseClause
CaseClauses CaseClause

CaseClause :

case Expression : StatementListopt

DefaultClause :

default : StatementListopt

Семантика

Для вычисления SwitchStatement : switch ( Expression ) CaseBlock выполняются следующие шаги:

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

  2. Пусть R будет результатом вычисления CaseBlock Блок выбора с передачей ему в качестве параметра GetValue(exprRef).

  3. Если R.type равно break, и R.target принадлежит к текущему набору меток, вернуть (normal, R.value, empty).

  4. Вернуть R.

Для вычисления CaseBlock : { CaseClausesopt}, которому передаётся входной параметр input, выполняются следующие шаги:

  1. Пусть V = empty.

  2. Пусть A будет списком элементов для CaseClause Выражение выбора по порядку исходного текста.

  3. Пусть searching поиск будет true.

  4. Повторять, пока searching равно true.

    1. Пусть C будет следующим CaseClause в A. Если такого CaseClause нет, вернуть (normal, V, empty).

    2. Пусть clauseSelector Селектор выражения будет результатом вычисления C.

    3. Если input равно clauseSelector согласно определению оператора ===, то

      1. Присвоить searching значение false.

      2. Если C имеет StatementList, то

        1. Произвести вычисление StatementList для C, и пусть R будет результатом.

        2. Если Rнепредвиденное завершение, вернуть R.

        3. Пусть V =R.value.

  5. Повторить

    1. Пусть C будет следующим CaseClause в A. Если такого CaseClause нет, вернуть (normal, V, empty).

    2. Если C имеет StatementList, то

      1. Произвести вычисление StatementList для C, и пусть R будет результатом.

      2. Если R.value не равно empty, то пусть V =R.value.

      3. Если Rнепредвиденное завершение, то вернуть (R.type,V,R.target).

Для вычисления CaseBlock : { CaseClausesoptDefaultClause CaseClausesopt} которому передаётся входной параметр input, выполняются следующие шаги:

  1. Пусть V = empty.

  2. Пусть A будет списком элементов для CaseClause в первом CaseClauses Выражения выбора по порядку исходного текста.

  3. Пусть B будет списком элементов для CaseClause во втором CaseClauses по порядку исходного текста.

  4. Пусть found найдено будет false.

  5. Повторить, при этом пусть C будет по порядку каждым CaseClause в A

    1. Если found равно false, то

      1. Пусть clauseSelector будет результатом вычисления C.

      2. Если input равно clauseSelector согласно определению оператора ===, то присвоить found значение true.

    2. Если found равно true, то

      1. Если C имеет StatementList, то

        1. Произвести вычисление StatementList для C, и пусть R будет результатом.

        2. Если R.value не равно empty, то пусть V =R.value.

        3. Если Rнепредвиденное завершение, то вернуть (R.type,V, R.target).

  6. Пусть foundInB найдено в B будет false.

  7. Если found равно false, то

    1. Повторять, пока foundInB равно false и пока не были обработаны все элементы в B.

      1. Пусть C будет следующим CaseClause в B.

      2. Пусть clauseSelector будет результатом вычисления C.

      3. Если input равно clauseSelector согласно определению оператора ===, то

        1. Присвоить foundInB значение true.

        2. Если C имеет StatementList, то

          1. Произвести вычисление StatementList для C, и пусть R будет результатом.

          2. Если R.value не равно empty, то пусть V =R.value.

          3. Если Rнепредвиденное завершение, то вернуть (R.type,V, R.target).

  1. Если foundInB равно false, и the DefaultClause Выражение по умолчанию имеет StatementList, то

    1. Произвести вычисление StatementList для DefaultClause, и пусть R будет результатом.

    2. Если R.value не равно empty, то пусть V =R.value.

    3. Если Rнепредвиденное завершение, то вернуть (R.type,V,R.target).

  2. Повторить (Обратите внимание, что если был выполнен шаг 7.a.i, то этот цикл не запустится в начале B).

    1. Пусть C будет следующим CaseClause в B. Если такого CaseClause нет, вернуть (normal, V, empty).

    2. Если C имеет StatementList, то

      1. Произвести вычисление StatementList для C, и пусть R будет результатом.

      2. Если R.value не равно empty, то пусть V =R.value.

      3. Если Rнепредвиденное завершение, то вернуть (R.type,V,R.target).

Для вычисления CaseClause : case Expression : StatementListopt выполняются следующие шаги:

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

  2. Вернуть GetValue(exprRef).

ПРИМЕЧАНИЕ При вычислении CaseClause не выполняется ассоциированный StatementList, а просто вычисляется Expression и возвращается значение, с помощью которого алгоритм CaseBlock определяет, какой StatementList нужно начать выполнять.

12.12 Инструкции с метками #

Синтаксис

LabelledStatement :

Identifier : Statement

Семантика

Перед инструкцией Statement может находиться метка. Инструкции с метками используются только совместно с инструкциями break и continue с метками. Инструкции goto в языке ECMAScript нет.

Программа на ECMAScript считается синтаксически некорректной, если она содержит LabelledStatement Инструкция с меткой, вложенную в инструкцию LabelledStatement, у которой Identifier аналогичен метке. Это не относится к меткам перед телом объявления функции FunctionDeclaration, которое прямо или косвенно вложено в инструкцию с меткой.

Для вычисления Identifier : Statement необходимо добавить Identifier к набору меток для Statement, и затем вычислить Statement. Если у LabelledStatement набор меток не пуст, эти метки также добавляются к набору меток для Statement перед его вычислением. Если при вычислении Statement получено (break, V, L), где L равно Identifier, то результат равен (normal, V, empty).

Перед вычислением значения LabelledStatement вложенная инструкция Statement считается имеющей пустой набор меток, если только она не представляет собой IterationStatement или SwitchStatement, и в этом случае она считается имеющей набор меток из одного элемента – empty.

12.13 Инструкция throw #

Синтаксис

ThrowStatement:

throw [no LineTerminator here] Expression ;

Семантика

Для вычисления значения ThrowStatement : throw [no LineTerminator here] Expression ; выполняются следующие шаги:

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

  2. Вернуть (throw, GetValue(exprRef), empty).

12.14 Инструкция try #

Синтаксис

TryStatement :

try Block Catch
try Block Finally
try Block Catch Finally

Catch :

catch ( Identifier) Block

Finally :

finally Block

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

Семантика

Для вычисления TryStatement : try Block Catch выполняются следующие шаги:

  1. Пусть B будет результатом вычисления Block.

  2. Если B.type не равно throw, вернуть B.

  3. Вернуть результат вычисления Catch с параметром B.

Для вычисления TryStatement : try Block Finally выполняются следующие шаги:

  1. Пусть B будет результатом вычисления Block.

  2. Пусть F будет результатом вычисления Finally.

  3. Если F.type равно normal, вернуть B.

  4. Вернуть F.

Для вычисления TryStatement : try Block Catch Finally выполняются следующие шаги:

  1. Пусть B будет результатом вычисления Block.

  2. Если B.type равно throw, то

    1. Пусть C будет результатом вычисления Catch с параметром B.

  3. Иначе, B.type не равно throw,

    1. Пусть C будет B.

  4. Пусть F будет результатом вычисления Finally.

  5. Если F.type равно normal, вернуть C.

  6. Вернуть F.

Для вычисления Catch : catch ( Identifier) Block выполняются следующие шаги:

  1. Пусть C будет параметром, который был передан в это порождающее правило.

  2. Пусть oldEnv будет Лексическим Окружением активного контекста исполнения.

  3. Путь catchEnv будет результатом вызова абстрактной операции NewDeclarativeEnvironment с передачей oldEnv в качестве аргумента.

  4. Вызвать конкретный метод CreateMutableBinding для catchEnv, передавая в качестве аргумента строковое значение Identifier.

  5. Вызвать конкретный метод SetMutableBinding для catchEnv, передавая в качестве аргументов Identifier, C и false. Обратите внимание, что последний аргумент в данной ситуации является несущественным.

  6. Присвоить LexicalEnvironment текущего контекста исполнения значение catchEnv.

  7. Пусть B будет результатом вычисления Block.

  8. Присвоить LexicalEnvironment текущего контекста исполнения значение oldEnv.

  9. Вернуть B.

ПРИМЕЧАНИЕ Независимо о того, каким образом управление выходит из блока Block, лексическое окружение LexicalEnvironment всегда восстанавливается до своего начального состояния.

Для вычисления Finally : finally Block выполняются следующие шаги:

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

12.14.1 Ограничения строгого режима #

Если TryStatement вместе с Catch встречается в строгом коде, и при этом Identifier для Catch представляет собой либо "eval", либо "arguments", генерируется SyntaxError.

12.15 Инструкция debugger #

Синтаксис

DebuggerStatement :

debugger ;

Семантика

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

Для вычисления DebuggerStatement : debugger ; выполняются следующие шаги:

  1. Если присутствует и включен отладчик, заданный реализацией, то

    1. Выполнить действие по отладке, заданное реализацией.

    2. Пусть result будет значением Completion, заданным реализацией.

  2. Иначе

    1. Пусть result будет (normal, empty, empty).

  3. Вернуть result.