diff options
Diffstat (limited to 'files/ru/web/javascript/reference/statements/try...catch')
-rw-r--r-- | files/ru/web/javascript/reference/statements/try...catch/index.html | 422 |
1 files changed, 422 insertions, 0 deletions
diff --git a/files/ru/web/javascript/reference/statements/try...catch/index.html b/files/ru/web/javascript/reference/statements/try...catch/index.html new file mode 100644 index 0000000000..3609136b03 --- /dev/null +++ b/files/ru/web/javascript/reference/statements/try...catch/index.html @@ -0,0 +1,422 @@ +--- +title: try...catch +slug: Web/JavaScript/Reference/Statements/try...catch +tags: + - JavaScript + - Исключение + - Ошибка +translation_of: Web/JavaScript/Reference/Statements/try...catch +--- +<div>{{jsSidebar("Statements")}}</div> + +<p>Конструкция <code>try...catch</code> пытается выполнить инструкции в блоке <code>try</code>, и, в случае ошибки, выполняет блок <code>catch</code>.</p> + +<h2 id="Синтаксис">Синтаксис</h2> + +<pre class="syntaxbox">try { + <em>try_statements</em> +} +[catch (<em>exception_var_1</em> if <em>condition_1</em>) { // не стандартно + <em>catch_statements_1</em> +}] +... +[catch (<em>exception_var_2</em>) { + <em>catch_statements_2</em> +}] +[finally { + <em>finally_statements</em> +}] +</pre> + +<dl> + <dt><code>try_statements</code></dt> + <dd>Инструкции для выполнения.</dd> +</dl> + +<dl> + <dt><code>catch_statements_1</code>, <code>catch_statements_2</code></dt> + <dd> + <p>Инструкции, которые будут выполнены, если произойдёт ошибка в блоке <code><font face="Consolas, Liberation Mono, Courier, monospace">try</font></code>.</p> + </dd> +</dl> + +<dl> + <dt><code>exception_var_1</code>, <code>exception_var_2</code></dt> + <dd>Идентификатор для хранения объекта ошибки, который впоследствии используется в блоке <code>catch</code></dd> +</dl> + +<dl> + <dt><code>condition_1</code></dt> + <dd>Условное выражение.</dd> +</dl> + +<dl> + <dt><code>finally_statements</code></dt> + <dd>Инструкции, которые выполняются после завершения блока <code>try</code>. Выполнение происходит в независимости от того, произошла ошибка или нет.</dd> +</dl> + +<h2 id="Описание">Описание</h2> + +<p>Конструкция <code>try</code> содержит блок <code>try</code>, в котором находится одна или несколько инструкций (Блок (<code>{}</code> ) обязательно должен присутствовать, даже если выполняется всего одна инуструкция), и хотя бы один блок <code>catch</code> или <code>finally</code>. Таким образом, есть три основные формы конструкции <code>try</code>:</p> + +<ol> + <li><code>try {...} catch {...}</code></li> + <li><code>try {...} finally {...}</code></li> + <li><code>try {...} catch {...} finally {...}</code></li> +</ol> + +<p>Блок <code>catch</code> содержит инструкции, которые будут выполнены, если в блоке <code>try</code> произошла ошибка. Если любая инструкция в блоке <code>try</code> выбрасывает исключение, то управление сразу же переходит в блок <code>catch</code>. Если в блок <code>try</code> не было выброшено исключение, то блок <code>catch</code> не выполняется.</p> + +<p>Блок <code>finally</code> выполнится после выполнения блоков <code>try</code> и <code>catch</code>, но перед инструкциями, следующими за конструкцией <code>try...catch</code>. Он выполняется всегда, в независимости от того, было исключение или нет.</p> + +<p>Вы можете использовать вложенные конструкции <code>try</code>. Если внутренняя конструкция <code>try</code> не имеет блока <code>catch</code> (такое может быть при её использовании в виде <code>try {...} finaly {...}</code>, потому что <code>try {...}</code> не может быть без блоков <font face="consolas, Liberation Mono, courier, monospace"><span style="background-color: rgba(220, 220, 220, 0.5);">catch</span></font> или <code>finally</code>), будет вызван <code>сatch</code> внешней конструкции <code>try</code>.</p> + +<p>Конструкция <code>try</code> также используется для обработки исключений JavaScript (то есть, выброшенных внутренними функциями языка или парсером). Загляните в <a href="/ru-RU/docs/Web/JavaScript/Guide">JavaScript руководство</a> для дополнительной информации о JavaScript исключениях.</p> + +<h3 id="Безусловный_блок_catch">Безусловный блок catch</h3> + +<p>При использовании блока <code>catch</code>, он вызывается для любого исключения в блоке <code>try</code>. Например, когда в следующем коде происходит ошибка, управление переходит к блоку <code>catch</code>.</p> + +<pre class="brush: js">try { + throw 'myException'; // создание исключения +} +catch (e) { + // инструкции для обработки ошибок + logMyErrors(e); // передать объект исключения обработчику ошибок +} +</pre> + +<p>Блок <code>catch</code> задает идентификатор (<code>e</code> в примере выше) который содержит объект исключения (в примере выше — значение, переданное оператору <code>throw</code>). Область видимости этого объекта ограничивается блоком <code>catch</code>.</p> + +<h3 id="Условный_блок_catch">Условный блок <code>catch</code></h3> + +<p>"Условные блоки <code>catch</code>" можно создавать, используя <code>try...catch</code> с <code>if...else if...else</code>, как здесь:</p> + +<pre class="brush: js">try { + myroutine(); // может выбрасывать три вида исключений +} catch (e) { + if (e instanceof TypeError) { + // обработка исключения TypeError + } else if (e instanceof RangeError) { + // обработка исключения RangeError + } else if (e instanceof EvalError) { + // обработка исключения EvalError + } else { + // обработка остальных исключений + logMyErrors(e); // передать обработчику ошибок + } +}</pre> + +<p>Частый сценарий использованя — обработать известные исключения, а при неизвестных ошибках, пробросить их дальше:</p> + +<pre class="brush: js">try { + myRoutine(); +} catch(e) { + if (e instanceof RangeError) { + // обработка известного исключения, с которым + // понятно, что делать + } else { + throw e; // пробросить неизвестные ошибки + } +} +</pre> + +<div class="blockIndicator note"> +<p><strong>Обратите внимание</strong>: Firefox раньше поддерживал краткую запись условных блоков <code>catch</code>:</p> + +<pre>try { + myroutine(); // может выбрасывать три вида исключения +} catch (e if e instanceof TypeError) { + // обработка исключений TypeError +} catch (e if e instanceof RangeError) { + // обработка исключений RangeError +} catch (e if e instanceof EvalError) { + // обработка исключений EvalError +} catch (e) { + // обработка остальных исключения + logMyErrors(e); +} +</pre> + +<p>Однако, такой синтаксис никогда не был частью спецификации ECMAScript и был удалён из Firefox после версии 59. Сейчас он не поддерживается ни в одном браузере.</p> +</div> + +<h3 id="Идентификатор_исключения">Идентификатор исключения</h3> + +<p>Когда в блоке <code>try</code> выбрасывается исключение, <code>exception_var</code> (т. е. <code>e</code> в конструкции <code>catch (e)</code>) содержит значение исключения. Его можно использовать, чтобы получить больше информации об выброшенном исключении. Идентификатор доступен только в <a href="https://wiki.developer.mozilla.org/docs/Glossary/Scope">области видимости</a> блока <code>catch</code>.</p> + +<pre class="brush: js">try { + if (!firstValidation()) { + throw 1; + } + if (!secondValidation()) { + throw 2; + } +} catch (e) { + // Выводит 1 или 2 (если не произошло никакх других ошибок) + console.log(e); +}</pre> + +<h3 id="Блок_finally">Блок finally</h3> + +<p>Блок <code>finally</code> содержит код который будет запущен после кода в блоках <code>try</code> и <code>catch</code>. Обратите внимание, что код в блоке <code>finally</code> запускается в независимости от того, было ли выброшено исключение или нет. Также код в блоке <code>finally</code> будет запущен вне зависимости от того, присутствует блок <code>catch</code> или нет. Блок <code>finally</code> можно использовать для того, чтобы скрипт безопасно завершил работу в случае ошибки. Например, если необходимо освободить память и ресурсы которые использовал скрипт.</p> + +<p>Наличие специального блока, связанного с ошибкой, который выполняется вне зависимости от наличия исключительной ситуации, может показаться странным, но эта конструкция на самом деле весьма полезна. Рассмотрим пример кода:</p> + +<pre class="brush: js">function expensiveCalculations() { + // Сложные вычисления +} + +function maybeThrowError() { + // Функция, которая может выбросить исключение + if(Math.random() > 0.5) throw new Error() +} + +try { + // Теперь при прокрутке страницы будут происходить + // сложные вычисления, что сильно скажется на + // производительности + window.addEventListener('scroll', expensiveCalculations) + maybeThrowError() +} catch { + // Если функция maybeThrowError выбросит исключения, + // управление сразу перейдёт в блок catch и + // сложные вычисления продолжат выполняться до + // перезагрузки страницы + maybeThrowError() +} +window.removeEventListener('scroll', expensiveCalculations)</pre> + +<p>В этом примере, если функция <code>maybeThrowError</code> выбросит исключение внутри блока <code>try</code>, управление перейдёт в блок <code>catch</code>. Если и в блоке <code>catch</code> эта функция тоже выбросит исключение, то выполнение кода прервётся, и обработчик события не будет снят, пока пользователь не перезагрузит страницу, что плохо скажется на скорости работы. Для того, чтобы избежать таких ситуаций, следует использовать блок <code>finally</code>:</p> + +<pre class="brush: js">try { + window.addEventListener('scroll', expensiveCalculations) + maybeThrowError() +} catch { + maybeThrowError() +} finally { + window.removeEventListener('scroll', expensiveCalculations) +} + +</pre> + +<p>Другой пример: работа с файлами. В следующем фрагменте кода показывается, как скрипт открывает файл и записывает в него какие-то данные (в серверном окружении JavaScript имеет доступ к файловой системе). Во время записи может произойти ошибка. Но после открытия файл очень важно закрыть, потому что незакрытый файл может привести к утечкам памяти. В таких случях используется блок <code>finally</code>:</p> + +<pre class="brush: js">openMyFile(); +try { + // Сделать что-то с файлом + writeMyFile(theData); +} +finally { + closeMyFile(); // Закрыть файл, что бы ни произошло +} +</pre> + +<h2 id="Примеры">Примеры</h2> + +<h3 id="Вложенные_блоки_try">Вложенные блоки try</h3> + +<p>Для начала давайте посмотрим что делает этот код:</p> + +<pre class="brush: js">try { + try { + throw new Error('упс'); + } + finally { + console.log('finally'); + } +} +catch (e) { + console.error('внешний блок catch', e.message); +} + +// Вывод: +// "finally" +// "внешний блок catch" "упс" +</pre> + +<p>Теперь отловим исключение во внутреннем блоке <code>try</code>, добавив к нему блок <code>catch</code>:</p> + +<pre class="brush: js">try { + try { + throw new Error('упс'); + } + catch (e) { + console.error('внутренний блок catch', e.message); + } + finally { + console.log('finally'); + } +} +catch (e) { + console.error('внешний блок catch', e.message); +} + +// Output: +// "внутренний блок catch" "упс" +// "finally" +</pre> + +<p>Наконец, пробросим ошибку</p> + +<pre class="brush: js">try { + try { + throw new Error('упс'); + } + catch (e) { + console.error('внутренний блок catch', e.message); + throw e; + } + finally { + console.log('finally'); + } +} +catch (e) { + console.error('внешний блок catch', e.message); +} + +// Вывод: +// "внутренний блок catch" "oops" +// "finally" +// "внешний блок catch" "oops" +</pre> + +<p>Любое исключение будет передано только в ближайший блок <code>catch</code>, если он не пробросит его дальше. Все исключения, выброшенными внутренними блоками (потому что код в блоке <code>catch</code> также может выбросить исключение), будут пойманы внешними.</p> + +<h3 id="Возвращение_значения_из_блока_finally">Возвращение значения из блока finally</h3> + +<p>Если блок <code>finally</code> возвращает какое-либо значение, оно становится значением, которое возвращает вся конструкция <code>try...catch...finally</code>, вне зависимости от любых инструкций <code>return</code> в блоках <code>try</code> и <code>catch</code>. Также игнорируются исключения, выброшенные блоком <code>catch</code>.</p> + +<pre class="brush: js">try { + try { + throw new Error('упс'); + } + catch (e) { + console.error('внутренний блок catch', e.message); + throw e; + } + finally { + console.log('finally'); + return; + } +} +catch (e) { + console.error('внешний блок catch', e.message); +} + +// Output: +// "внутренний блок catch" "упс" +// "finally" +</pre> + +<p>"упс" не доходит до внешнего блока из-за инструкции <code>return</code> в блоке <code>finally</code>. То же самое произойдёт с любым значением, возвращаемым из блока <code>catch</code>.</p> + +<h2 id="Спецификации">Спецификации</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Спецификация</th> + <th scope="col">Состояние</th> + <th scope="col">Примечание</th> + </tr> + <tr> + <td>{{SpecName('ES3')}}</td> + <td>{{Spec2('ES3')}}</td> + <td>Изначальная редакция. Реализовано в JavaScript 1.4</td> + </tr> + <tr> + <td>{{SpecName('ES5.1', '#sec-12.14', 'try statement')}}</td> + <td>{{Spec2('ES5.1')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-try-statement', 'try statement')}}</td> + <td>{{Spec2('ES6')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-try-statement', 'try statement')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td>Not part of the current ECMA-262 standard: Multiple catch clauses and conditional clauses (SpiderMonkey extension, JavaScript 1.5).</td> + </tr> + </tbody> +</table> + +<h2 id="Совместимость">Совместимость</h2> + +<p>{{CompatibilityTable}}</p> + +<div id="compat-desktop"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Chrome</th> + <th>Firefox (Gecko)</th> + <th>Internet Explorer</th> + <th>Opera</th> + <th>Safari</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatGeckoDesktop("6")}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + </tr> + <tr> + <td>Conditional clauses<br> + (non-standard)</td> + <td>{{CompatNo}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + </tr> + </tbody> +</table> +</div> + +<div id="compat-mobile"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Android</th> + <th>Chrome for Android</th> + <th>Firefox Mobile (Gecko)</th> + <th>IE Mobile</th> + <th>Opera Mobile</th> + <th>Safari Mobile</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + </tr> + <tr> + <td>Conditional clauses<br> + (non-standard)</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + </tr> + </tbody> +</table> +</div> + +<h2 id="См._также">См. также</h2> + +<ul> + <li>{{jsxref("Error")}}</li> + <li>{{jsxref("Statements/throw", "throw")}}</li> +</ul> |