Как бы я различал разные типы исключений?
Я начинаю изучать JavaScript, пока не проблема, но мне трудно найти хорошее объяснение механизма Exception в JS.
Похоже на С++, JS позволяет бросать вокруг каждого объекта, а не просто бросать объект Exception (возможно, из-за него динамический характер).
throw 'An error occured.';
работает, а также
throw new Exception('An error occured.');
catch
и finally
оба, похоже, работают как их эквивалент Java. Тем не менее, я не знаю, какие широко распространенные рекомендации относительно исключений.
Так, например, законно ли бросать объекты типа string, например:
throw 'An error occured';
Как бы я различал различные типы исключений?
Ответы
Ответ 1
Исключение броска и ловушки довольно дорого, а с помощью JavaScript вы в первую очередь будете получать исключения в случаях, например, когда вы пытаетесь проанализировать строку JSON, которая была отформатирована. Я бы предложил избегать try/catch как можно больше и вместо этого сосредоточиться на проверке ошибок на старом способе (возвращаемые типы, убедившись, что переменные правильно инициализированы перед их использованием и т.д.), Поскольку исключения здесь менее вероятны, чем в С++ или особенно Java или .NET.
Рекомендация Andy E является хорошей для их обработки, но в целом вы должны попытаться написать код JavaScript защитно, чтобы вам даже не нужно было попробовать/поймать. Помните, что даже JITed JavaScript в Chrome (самый быстрый движок) по-прежнему медленный, как черт по сравнению с Java или С#, не говоря уже о С++, поэтому все, что дорого стоит на этих языках, скорее всего будет в JavaScript.
Ответ 2
"Лучшая практика", я полагаю, заключается в том, чтобы выбросить правильный тип объекта Error, связанный с проблемой, вызывающей исключение. ECMAScript определяет несколько типов объектов исключения, все из которых наследуются от Error
. Этими объектами являются EvalError
, RangeError
, ReferenceError
, TypeError
и URIError
.
Эти конструкторы используются встроенными функциями ECMAScript, что позволяет вам сделать что-то вроде этого:
try {
// do something
}
catch (e) {
if (e instanceof TypeError) {
// do something else
}
}
Как правило, использование оператора throw
без использования объекта исключения поражает меня как плохую практику по нескольким причинам, в том числе:
- Код, предназначенный для обработки исключений, может ожидать объект
Error
, получение примитива может привести к неожиданным побочным эффектам или невозможности обработать исключение без изменения кода обработки. Примером этого является отсутствие свойства stack
в результате выражения throw.
- Если не используется в заявлении try/catch, Internet Explorers 8 и ниже будут бросать другое исключение при попытке бросить, с сообщением "Исключение брошено и не поймано" *. Это может быть еще более запутанным, если вы отлаживаете использование инструментов разработчика или имеете глобальный обработчик исключений, установленный в
window.onerror
.
Итак, да, в общем, нужно правильно бросать экземпляры Error
или его наследующие объекты.
* nb, IE также делает это для типов объектов Error, которые не построены непосредственно из Error
. Да, я знаю, что это глупо, но они исправили его в IE 9, хотя они сказали мне, что это "по дизайну".
Ответ 3
Если вы создаете приложение AJAX, исключения могут быть не столь полезными. Из-за асинхронного характера операций ajax обработка ошибок не будет работать, как вы можете ожидать
function save_data(){
try {
ajax(some_ulr, function(){
//callback
do_wrong_thing();
});
} catch(e){
handler_error();
}
}
в приведенном выше фрагменте кода, ошибка, вызванная do_wrong_thing, не вызывает секцию catch.