Return f;
}
Когда генерируется исключение, интерпретатор JavaScript немедленно прерывает нормальное исполнение программы и переходит к ближайшему обработчику исключений.
В обработчиках исключений используется конструкция catch инструкции try/catch/finally. Если блок кода, в котором возникло исключение, не имеет соответствующей конструкции catch, интерпретатор анализирует следующий внешний блок кода и проверяет, связан ли с ним обработчик исключений. Это продолжается до тех пор, пока обработчик не будет найден. Если исключение генерируется в функции, не содержащей инструкции try/catch/finally, предназначенной для его обработки, то исключение распространяется на код, вызвавший функцию. Так исключения распространяются по лексической структуре методов JavaScript вверх по стеку вызовов. Если обработчик исключения так и не будет найден, исключение рассматривается как ошибка и о ней сообщается пользователю.
Инструкция throw стандартизована в ECMAScript v3 и реализована в JavaScript 1.4. Класс Error и его подклассы также являются частью стандарта ECMAScript v3, но они не были реализованы до JavaScript 1.5.
Инструкция try/catch/finally
Инструкция try/catch/finally реализует механизм обработки исключений в JavaScript. Конструкция try в этой инструкции просто определяет блок кода, в котором обрабатываются исключения.
За блоком try следует конструкция catch с блоком инструкций, вызываемых, когда где-либо в блоке try возникает исключение.
За конструкцией catch следует блок finally, содержащий код зачистки, который гарантированно выполняется независимо от того, что происходит в блоке try. И блок catch, и блок finally не являются обязательными, однако после блока try должен обязательно присутствовать хотя бы один из них. Блоки try, catch и finally начинаются и заканчиваются фигурными скобками. Это обязательная часть синтаксиса и она не может быть опущена, даже если между ними содержится только одна инструкция. Как и инструкция throw, инструкция try/catch/finally стандартизована в ECMAScript v3 и реализована в JavaScript 1.4.
Следующий фрагмент иллюстрирует синтаксис и суть инструкции try/catch/finally. Обратите внимание, в частности, на то, что за ключевым словом catch следует идентификатор в скобках. Этот идентификатор похож на аргумент функции. Он присваивает имя локальной переменной, существующей только в теле блока catch. JavaScript присваивает этой переменной объект исключения или значение, указанное при генерации исключения:
try {
// Обычно этот код без сбоев работает от начала до конца.
// Но в какой-то момент в нем может генерироваться исключение
// либо непосредственно с помощью инструкции throw, либо косвенно
// вызовом метода, генерирующего исключение.
}
catch (e) {
// Инструкции в этом блоке выполняются тогда и только тогда, когда
// в блоке try генерируется исключение. Эти инструкции могут
// использовать локальную переменную e, ссылающуюся на объект Error
// или на другое значение, указанное в инструкции throw. Этот блок может
// либо каким-то образом обработать исключение, либо проигнорировать
// его, делая что-то другое, либо заново сгенерировать исключение
// с помощью инструкции throw.
}
finally {
// Этот блок содержит инструкции, которые выполняются всегда, независимо
// от того, что произошло в блоке try. Они выполняются, если блок try прерван:
// 1) нормальным образом, достигнув конца блока
// 2) из-за инструкции break, continue или return
// 3) с исключением, обработанным приведенным ранее блоком catch
// 4) с неперехваченным исключением, которое продолжает свое
// распространение на более высокие уровни
}
Пример:
try {
// Просим пользователя ввести число
var n = prompt("Введите положительное число", "");
var f = factorial(n); // Вычисляем факториал числа,
//предполагая, что входные данные корректны
alert(n + "! = " + f); // Показываем результат
}
catch (ex) {// Если введенные данные некорректны, мы попадем сюда
alert(ex); // Сообщаем пользователю об ошибке
}
Это пример инструкции try/catch без конструкции finally. Хотя finally используется не так часто, как catch, тем не менее иногда эта конструкция оказывается полезной. Рассмотрим ее поведение подробнее.
Блок finally гарантированно исполняется, если исполнялась хотя бы какая-то часть блока try, независимо от того, каким образом завершился код в блоке try. Эта возможность обычно используется для очистки после выполнения кода в предложении try.
В обычной ситуации управление доходит до конца блока try, а затем переходит к блоку finally, который выполняет всю необходимую очистку. Если управление вышло из блока try из-за инструкций return, continue или break, перед передачей управления в другое место кода исполняется блок finally.
Если в блоке try возникает исключение и имеется соответствующий блок catch для его обработки, управление сначала передается в блок catch, а затем – в блок finally. Если отсутствует локальный блок catch, то управление сначала передается в блок finally, а затем переходит на ближайший внешний блок catch, который может обработать исключение.
Если сам блок finally передает управление с помощью инструкции return, continue, break или throw или путем вызова метода, генерирующего исключение, незаконченная команда на передачу управления отменяется и выполняется новая.
Например, если блок finally генерирует исключение, это исключение заменяет любое сгенерированное исключение. Если в блоке finally имеется инструкция return, происходит нормальный выход из метода, даже если генерировалось исключение, которое не было обработано.
Инструкции try и finally могут использоваться вместе без конструкции catch.
В этом случае блок finally – это просто код зачистки, который будет гарантированно исполнен независимо от наличия в блоке try инструкции break, continue или return. Например, в следующем коде используется инструкция try/finally, гарантирующая, что счетчик цикла будет инкрементирован в конце каждой итерации, даже если итерация внезапно прервется инструкцией continue:
var i = 0, total = 0;
while(i < a.length) {
try {
if ((typeof a[i] != "number") || isNaN(a[i]))// Если это не число,
continue;// переходим к следующей итерации цикла.
total += a[i];// В противном случае добавляем число к общей сумме.
}
finally {
i++;// Всегда увеличиваем i, даже если ранее была инструкция continue.
}
}
Дата добавления: 2015-08-01; просмотров: 570;