aboutsummaryrefslogtreecommitdiff
path: root/files/ru/web/javascript/reference/statements/try...catch/index.html
diff options
context:
space:
mode:
Diffstat (limited to 'files/ru/web/javascript/reference/statements/try...catch/index.html')
-rw-r--r--files/ru/web/javascript/reference/statements/try...catch/index.html422
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() &gt; 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>