Перевод не завершен. Пожалуйста, помогите перевести эту статью с английского.

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

Синтаксис

try {
   try_statements
}
[catch (exception_var_1 if condition_1) { // не стандартно
   catch_statements_1
}]
...
[catch (exception_var_2) {
   catch_statements_2
}]
[finally {
   finally_statements
}]
try_statements
Инструкция, которая будет выполнена.
catch_statements_1, catch_statements_2

Инструкции, которые будут выполнены, если произойдёт ошибка в блоке try.

exception_var_1, exception_var_2
Идентификатор для хранения объекта ошибки, который впоследствии используется в блоке catch
condition_1
Выражение состояния
finally_statements
Инструкции, которые выполняются после завершения блока try. Выполнение происходит независимо от того, была ошибка или нет.

Описание

Конструкция try содержит блок try, в котором находится одна или несколько инструкций ({} должно быть всегда использовано, даже для одиночных инструкций), и как минимум один блок catch, или один блок finally, или оба. Здесь приведены три возможных варианта использования конструкции try:

  1. try...catch
  2. try...finally
  3. try...catch...finally

Блок catch содержит инструкции, которые будут выполнены, если в блоке try произошла ошибка. Это сделано для того, чтобы была возможность обработать ошибку в блоке catch, при её возникновении. Если какая-либо инструкция вызывает ошибку в try блоке, то управление незамедлительно переходит в блок catch. Если в try блоке не будет никакой ошибки, то блок catch пропустится.

Блок finally выполнится после выполнения блоков try и catch, но перед инструкциями, следующими за конструкцией try...catch. Этот блок всегда выполняется независимо от того, была ошибка или нет.

Вы можете размещать один или более try оператор. Если внутренний try оператор не имеет catch блок, будет использован сatch внешнего оператора try.

Вы также можете использовать оператор try для обработки JavaScript исключений. Загляните в JavaScript руководство для получения большей информации о JavaScript исключениях.

Специальный вызов ошибки

При специальном вызове ошибки, вход в блок catch происходит тогда, когда ошибка вызвана. Для примера, когда ошибка 'myException вызывается в следующем коде, управление переходит в блок catch незамедлительно:

try {
   throw 'myException'; // создание ошибки
}
catch (e) {
   // инструкции для работы с ошибками
   logMyErrors(e); // передает объект ошибки для управления им
}

Блок catch задает идентификатор (e в примере выше) который содержит заданное оператором throw. Блок catch в JavaScript создает идентификатор когда произошел вход в блок и добавляет его в область видимости блока; идентификатор действителен только во время исполнения блока catch; после того, как catch блок заканчивает свое исполнение идентификатор перестаёт быть доступным.

Условные catch обработчики

Не стандартно
Эта возможность не является стандартной и стандартизировать её пока никто не собирается. Не используйте её на сайтах, смотрящих во внешний мир: она будет работать не у всех пользователей. Также могут присутствовать большие несовместимости между реализациями и её поведение может в будущем измениться.

Вы также можете использовать один или несколько условных catch обработчиков чтобы отлавить конкретные исключения. В этом случае, подходящий catch блок сработает когда конкретное исключение будет выброшено. В этом примере, код вынутри блока try может выкинуть три типа исключений: TypeError, RangeError, и EvalError.
Когда будет выброшено исключение, управление передается подходящему блоку catch. Если исключение не соотсветствует ни одному из указаных типов и присутствует безусловный блок catch, то управление будет передано ему.

Если вы используете безусловный блок catch с одним или более условным блоком catch, то безусловный блок catch должен находиться в конце, иначе безусловный блок catch будет обрабатывать исключения любого типа до того, как они достигнут остальных.

Напоминание: Эта функциональность не является частью ECMAScript спецификации.

try {
    myroutine(); // может бросить три типа исключений
} catch (e if e instanceof TypeError) {
    // statements to handle TypeError exceptions
} catch (e if e instanceof RangeError) {
    // statements to handle RangeError exceptions
} catch (e if e instanceof EvalError) {
    // statements to handle EvalError exceptions
} catch (e) {
    // statements to handle any unspecified exceptions
    logMyErrors(e); // pass exception object to error handler
}

И вот пример того, как реализовать "условные catch-блоки" используя простой JavaScript согласно спецификации ECMAScript (очевидно, это более многословный способ но работает везде):

try {
    myroutine(); // может выкинуть три типа исключений
} catch (e) {
    if (e instanceof TypeError) {
        // код для обработки исключений TypeError
    } else if (e instanceof RangeError) {
        // код для обработки исключений RangeError
    } else if (e instanceof EvalError) {
        // код для обработки исключений EvalError
    } else {
       // код для обработки всех остальных типов исключений
       logMyErrors(e); // передача исключения обработчику исключений
    }
}

The exception identifier

When an exception is thrown in the try block, exception_var (e.g. the e in catch (e)) holds the value specified by the throw statement. You can use this identifier to get information about the exception that was thrown.

This identifier is local to the catch clause. That is, it is created when the catch clause is entered, and after the catch clause finishes executing, the identifier is no longer available.

Блок finally

Блок finally содержит код который будет запущен после кода в блоках try и catch. Обратите внимание, что код в блоке finally запускается вне зависимо от того, было ли выброшено исключение или нет. Также, если было выброшено исключение, код в блоке finally будет запущен вне зависимости от того,  присутствует ли блок catch или нет. Также вы можете использовать блок finally для того, чтобы скрипт безопасно завершил работу в случае ошибки. Например, вам необходимо освободить память и ресурсы которые скрипт использовал.

Наличие специального блока, связанного с ошибкой, который выполняется вне зависимости от наличия исключительной ситуации, может показаться странным, но эта конструкция на самом деле весьма полезна. Однако важно скорее не то, что код в finally выполняется всегда, а то, КОГДА код, который следует ЗА try...catch НЕ выполняется. К примеру: если в блоке catch ВНУТРЕННЕГО try...catch возникает исключение, весь оставшийся код ВНЕШНЕГО try...catch, который оборачивает внутренний (или же в основном потоке выполнения, если внешнего try...catch нету) не будет выполнен, так как контроль немедленно передаётся либо в catch ВНЕШНЕГО try...catch, либо во внутренний генератор исключений, если ВНЕШНИЙ try...catch отсутствует. По этой причине, любой код, предназначенный для очистки ресурсов, во внешней или внутренней секциях будет пропущен. Однако, если ВНУТРЕННИЙ try...catch содержит блок finally, тогда код этого finally будет выполнен ПЕРВЫМ, с целью позволить очистку ресурсов, и только ПОТОМ внешний catch (или же генератор исключений) получит контроль, что бы обработать новое исключение. И теперь, если эта очистка ресурсов должна быть выполнена вне зависимости от того, успешно ли выполнен код в try...catch, то, если бы блок finally выполнялся только после исключения, код очистки ресурсов нужно было бы продублировать что в finally (в случае когда исключения произошло), что в блоке try, если ошибки не было. Однако блок finally выполняется ВСЕГДА, вне зависимости от того было исключение или нет, и по этому нет причин не указать блок finally и дать ему выполняться вне зависимости от того была ошибка или нет.

The following example opens a file and then executes statements that use the file (server-side JavaScript allows you to access files). If an exception is thrown while the file is open, the finally clause closes the file before the script fails. The code in finally also executes upon explicitly returning from try or catch block.

openMyFile();
try {
   // tie up a resource
   writeMyFile(theData);
}
finally {
   closeMyFile(); // always close the resource
}

Примеры

Вложенные блоки try

Для начала давайте посмотрим что происходит с этим блоком кода:

try {
  try {
    throw new Error('oops');
  }
  finally {
    console.log('finally');
  }
}
catch (ex) {
  console.error('outer', ex.message);
}

// Вывод:
// "finally"
// "outer" "oops"

Now, if we already caught the exception in the inner try-block by adding a catch block

try {
  try {
    throw new Error('oops');
  }
  catch (ex) {
    console.error('inner', ex.message);
  }
  finally {
    console.log('finally');
  }
}
catch (ex) {
  console.error('outer', ex.message);
}

// Output:
// "inner" "oops"
// "finally"

И сейчас, давайте перевыбросим ошибку

try {
  try {
    throw new Error('oops');
  }
  catch (ex) {
    console.error('inner', ex.message);
    throw ex;
  }
  finally {
    console.log('finally');
  }
}
catch (ex) {
  console.error('outer', ex.message);
}

// Вывод:
// "inner" "oops"
// "finally"
// "outer" "oops"

Any given exception will be caught only once by the nearest enclosing catch-block, unless it is re-thrown. Of course, any new exceptions raised in the "inner" block (because code in catch-block may do something that throws), will be caught by the "outer" block.

Returning from a finally block

If the finally block returns a value, this value becomes the return value of the entire try-catch-finally production, regardless of any return statements in the try and catch blocks. This includes exceptions thrown inside of the catch block:

try {
  try {
    throw new Error('oops');
  }
  catch (ex) {
    console.error('inner', ex.message);
    throw ex;
  }
  finally {
    console.log('finally');
    return;
  }
}
catch (ex) {
  console.error('outer', ex.message);
}

// Output:
// "inner" "oops"
// "finally"

The outer "oops" is not thrown because of the return in the finally block. The same would apply to any value returned from the catch block.

Спецификации

Спецификация Состояние Примечание
ECMAScript 3rd Edition (ECMA-262) Стандарт Изначальная редакция. Реализовано в JavaScript 1.4
ECMAScript 5.1 (ECMA-262)
Определение 'try statement' в этой спецификации.
Стандарт  
ECMAScript 2015 (6th Edition, ECMA-262)
Определение 'try statement' в этой спецификации.
Стандарт  
ECMAScript Latest Draft (ECMA-262)
Определение 'try statement' в этой спецификации.
Живой стандарт Not part of the current ECMA-262 standard: Multiple catch clauses and conditional clauses (SpiderMonkey extension, JavaScript 1.5).

Совместимость

Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
Basic support (Да) 6 (6) (Да) (Да) (Да)
Conditional clauses
(non-standard)
Нет (Да) Нет Нет Нет
Feature Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Basic support (Да) (Да) (Да) (Да) (Да) (Да)
Conditional clauses
(non-standard)
Нет Нет (Да) Нет Нет Нет

См. также

Метки документа и участники

 Внесли вклад в эту страницу: illya-s, odin3, DavidWebb, nikitaermishin, NikitaCoder
 Обновлялась последний раз: illya-s,