Как бы я различал разные типы исключений?

Я начинаю изучать 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.