Предыдущие слова
Обработка ошибок имеет решающее значение для разработки веб -приложений. Он не может предсказать возможные ошибки заранее, и стратегии восстановления не могут быть приняты заранее, что может привести к плохому опыту пользователя. Поскольку любая ошибка JavaScript может привести к тому, что веб -страница не будет использоваться в качестве разработчика, вы должны знать, когда, почему и что произойдет. Эта статья подробно представляет механизм обработки ошибок в JavaScript
Объект ошибки
Объект ошибки - это объект, содержащий информацию об ошибке, и является собственным объектом JavaScript. Когда возникает ошибка во время анализа или запуска кода, двигатель JavaScript автоматически генерирует и бросает экземпляр объекта ошибки, а затем вся программа будет прервана при возникновении ошибки.
console.log (t); // uncaught referenceerror: t не определено
ECMA-262 указывает, что объект ошибки включает в себя два свойства: сообщение и имя. Атрибут сообщения сохраняет сообщение об ошибке, а атрибут имени сохраняет тип ошибки
Кода -копия выглядит следующим образом:
// Как правило, используйте оператор Try-Catch, чтобы поймать ошибки
пытаться{
Т;
} catch (ex) {
console.log (ex.message); // t не определено
console.log (ex.name); // referenceerror
}
Браузер также расширил свойства объекта ошибки и добавил другую соответствующую информацию. Среди них наиболее реализованным производителями браузеров является атрибут стека, который указывает информацию о трассировке стека (Safari не поддерживает его)
Кода -копия выглядит следующим образом:
пытаться{
Т;
} catch (ex) {
console.log (ex.stack); //@file: /// d: /wamp/www/form.html: 12: 2
}
Конечно, вы можете использовать конструктор error () для создания объекта ошибки. Если параметр сообщения указан, объект ошибки будет использовать его в качестве свойства сообщения; Если не указано, он будет использовать предопределенную строку по умолчанию в качестве значения свойства
Кода -копия выглядит следующим образом:
новая ошибка ();
новая ошибка (сообщение);
// Как правило, используйте оператор броска, чтобы бросить ошибки
Выбросить новую ошибку ('test'); // uncaught ошибка: тест
Выбросить новую ошибку (); // uncaught ошибка
Кода -копия выглядит следующим образом:
функция userError (сообщение) {
this.message = сообщение;
this.name = "userError";
}
UserError.prototype = new Error ();
UserError.prototype.constructor = userError;
бросить новый userError ("errormessage"); // uncauct userError: errorromSessage
Когда конструктор error () называется непосредственно как функция без использования нового оператора, его поведение такое же, как и при вызове нового оператора
Кода -копия выглядит следующим образом:
Ошибка();
Ошибка (сообщение);
ошибка бросания ('test'); // uncaught ошибка: тест
Выбросить ошибку (); // uncaught ошибка
Объект ошибки имеет метод ToString (), который возвращает атрибут сообщения объекта ошибки.
Кода -копия выглядит следующим образом:
var test = новая ошибка ('testerror');
console.log (test.toString ()); // 'error: testerror'
Тип ошибки
Существует много типов ошибок, которые могут возникнуть во время выполнения кода. Каждая ошибка имеет соответствующий тип ошибки, и когда возникает ошибка, будет брошен объект ошибки соответствующего типа. ECMA-262 определяет следующие 7 типов ошибок:
Кода -копия выглядит следующим образом:
Ошибка
Evalerr (Eval Error)
DrangeError (DrangeError)
ReferenceError (ссылка ошибка)
Синтаксисертор (синтаксическая ошибка)
TypeError (ошибка типа)
Urierror (ошибка URI)
Где ошибка - это базовый тип, а другие типы ошибок унаследованы от этого типа. Следовательно, все типы ошибок имеют набор одинаковых свойств. Ошибки типа ошибки редки, и если есть, они также брошены браузером; Основная цель этого базового типа - для разработчиков, чтобы бросить пользовательские ошибки
【Evalerror (Eval Erry)】
Когда функция Eval не выполнена правильно, будет выброшена ошибка Evalerror. Этот тип ошибки больше не появляется в ES5, но будет продолжать сохраняться, чтобы обеспечить совместимость с предыдущими кодами.
【DrangeError (DrangeError)】
Ошибка типа DrangeError будет запускаться, когда значение превышает соответствующий диапазон, в основном, включая превышение диапазона длины массива и превышение диапазона чисел значений.
Кода -копия выглядит следующим образом:
Новый массив (-1); // uncaught rayerror: неверная длина массива
Новый массив (number.max_value); // uncauge daryerror: неверная длина массива
(1234) .toexponential (21); // uncaught DrangeError: ToExponential () аргумент должен быть между 0 и 20
(1234) .toexponential (-1); //// unactaught dameerror: toexponential () аргумент должен быть между 0 и 20
【SupersError (ссылка ошибка)】
Ссылочный обход будет запускаться при ссылке на удивительную переменную или ошибку типа LVALUE.
a; // uncauge referenceerr: a не определено
1 ++; // uncaught referenceerror: неверная левая побочная
【SyntaxError (SyntaxError)】
Когда правила синтаксиса не будут соблюдены, будет выброшен синтаксисерр (синтаксическая ошибка)
Кода -копия выглядит следующим образом:
// Имя переменной неверно
var 1a; // uncaught syntaxError: неожиданное число
// отсутствующие кронштейны
Console.log 'hello'); // uncaught syntaxError: неожиданная строка
【TypeError (ошибка типа)】
Ошибка типа TypeError будет вызвана, когда неожиданные типы хранятся в переменных или при доступе к несуществующим методам. Хотя причины ошибок разнообразны, в конечном счете, это связано с тем, что тип переменной не соответствует требованиям при выполнении определенного типа операции.
Кода -копия выглядит следующим образом:
var o = new 10; // unaught typeerror: 10 не конструктор
Alert («имя» в True); // uncaught typeerror: невозможно использовать »в« операторе для поиска «Имя» в True
Function.prototype.tostring.call ('name'); // uncaught typeerror: function.prototype.toString не является общим
【Urierror (ошибка URI)】
Urierror-это ошибка, которая бросается, когда параметры функций, связанных с URI, неверны. В основном он включает в себя шесть функций: encodeuri (), decodeuri (), encodeuricomponent (), decodeuricomponent (), arceper () и unescape ().
decodeuri ('%2'); // urierror: uri Malformed
Событие ошибки
Любые ошибки, которые не обрабатываются через Try-Catch, запускают событие ошибки объекта окна
Событие ошибки может получить три параметра: сообщение об ошибке, URL, где находится ошибка, и номер строки. В большинстве случаев только сообщения об ошибках полезны, потому что URL -адрес предоставляет только местоположение документа, а номер строки относится к строке кода, которая может быть из встроенного кода JavaScript или из внешнего файла.
Чтобы указать обработчик событий ошибки, вы можете использовать технологию уровня DOM0 или использовать стандартный формат событий DOM2 уровня
Кода -копия выглядит следующим образом:
// уровень DOM0
window.onerror = function (сообщение, url, line) {
оповещение (сообщение);
}
// уровень DOM2
window.addeventlistener ("error", function (сообщение, url, line) {
оповещение (сообщение);
});
Отображает ли браузер стандартное сообщение об ошибке, зависит от возвращаемого значения Onerror. Если возвращаемое значение неверно, в консоли отображается сообщение об ошибке; Если возвратное значение верно, оно не отображается
Кода -копия выглядит следующим образом:
// Консоль отображает сообщение об ошибке
window.onerror = function (сообщение, url, line) {
оповещение (сообщение);
вернуть ложь;
}
а;
// Консоль не отображает сообщение об ошибке
window.onerror = function (сообщение, url, line) {
оповещение (сообщение);
вернуть истину;
}
а;
Этот обработчик событий является последней линией защиты, чтобы избежать ошибок отчетности браузеров. В идеале вы не должны использовать его, когда это возможно. Пока вы можете использовать оператор Try-Catch соответствующим образом, в браузере не будет передаваться ошибки, а событие ошибки не будет запускается.
Изображение также поддерживает события ошибок. Пока URL -адрес в SRC Характеристика изображения не может вернуть распознаваемый формат изображения, будет запускается событие ошибки. В настоящее время событие ошибки следует за форматом DOM и возвращает объект события, нацеленный на изображение как цель
Появится ящик для предупреждения, когда изображение загружается. Когда происходит событие ошибки, процесс загрузки изображения закончился, что означает, что его нельзя скачать снова.
Кода -копия выглядит следующим образом:
var image = new Image ();
image.src = 'smilex.gif';
image.onerror = function (e) {
console.log (e);
}
Заявление бросить и ошибки бросить
Оператор Thress используется для выброса ошибки. Когда ошибка выброшена, вы должны указать значение для оператора Thr. Какой тип это значение? Там нет требования.
[Примечание] Процесс броска ошибки заблокирован, и последующий код не будет выполнен
Кода -копия выглядит следующим образом:
бросить 12345;
бросить «привет мир»;
бросить правду;
бросить {name: 'javascript'};
Вы можете использовать оператор Thress, чтобы вручную выбросить объект ошибки
Кода -копия выглядит следующим образом:
бросить новую ошибку («что -то плохое случилось»);
Бросьте новый синтаксисратор («Я не люблю ваш синтаксис».);
Бросьте новый TypeError («За какую переменную вы меня взяли?»);
Бросьте новый RadeError («Извините, вы просто не имеете диапазона»);
бросить новый Evalerror («который не оценивает»);
бросить новый Urierror («uri, это ты?»);
Бросьте New ReferenceError («Вы не ссылались на свои ссылки правильно»);
Использование прототипов цепочек может также создавать пользовательские типы ошибок, унаследовав ошибку (прототипные сети представлены в главе 6). На этом этапе вам необходимо указать атрибуты имени и сообщения для недавно созданного типа ошибки
Браузер обрабатывает пользовательские типы ошибок, унаследованные от ошибок, как и другие типы ошибок. Создание пользовательской ошибки полезно, если вы хотите поймать ошибку, которую вы бросаете, и относиться к ней иначе, чем ошибка браузера.
Кода -копия выглядит следующим образом:
function CustomError (сообщение) {
this.name = 'CustomError';
this.message = сообщение;
}
CustomError.Prototype = new Error ();
бросить новый CustomError («Мое сообщение»);
Когда сталкивается оператор Throw, код немедленно прекратит выполнять выполнение. Код будет продолжать выполнять только в том случае, если оператор Try-Catch фиксирует значение брошенного.
Более подробное объяснение: когда будет брошено исключение, интерпретатор JavaScript немедленно остановит в настоящее время выполняющую логику и перейти к соседнему обработчику исключений. Обработчик исключений написан в пункте «Уловка» в заявлении о промежутке. Если кодовый блок, который бросает исключение, не имеет связанного пункта для улова, интерпретатор проверит блочный закрытый код более высокого уровня, чтобы увидеть, имеет ли он связанный обработчик исключений. И так далее, пока не найден обработчик исключений. Если функция, которая бросает исключение, не обрабатывает его оператор Try-Catch, исключение будет распространяться вверх до кода, который вызывает функцию. Таким образом, исключение будет распространяться вверх по лексической структуре метода JavaScript и стека вызовов. Если обработчик исключений не найден, JavaScript будет обрабатывать исключение как ошибку программы и сообщить об этом пользователю
Попробуйте оператор поймать и поймайте ошибку
ECMA-262 Edition 3 представляет оператор Try-Catch как стандартный способ обработки исключений в JavaScript, используется для улавливания и обработки ошибок
Среди них пункт TRY определяет кодовый блок, где расположены исключения, которые необходимо обрабатывать. Предложение по уловке следует за пунктом Try. Когда исключение происходит где -то в блоке Try, вызывает логику кода внутри улова. За предложением о захвате следует наконец -то блок, где расположен код очистки. Независимо от того, происходит ли исключение в блоке Try, логика внутри блока, наконец, всегда будет выполнена. Хотя улова и, наконец, необязательны, пункт TRY требует, чтобы по крайней мере одно из двух сформировало полное утверждение.
Все блоки операторов Try/Catch/наконец должны быть заключены в кудрявые брекеты. Брекеты здесь требуются. Даже если в пункте есть только одно утверждение, вьющиеся скобки не могут быть опущены.
пытаться{
// вообще говоря, код здесь начнется с начала до конца без каких -либо проблем
// но иногда исключение бросается, либо непосредственно выбрасывается оператором броска, либо косвенно, вызывая метод
} catch (e) {
// если и только тогда, когда исключение брошено блоком операторов try, код здесь будет выполнен
// Здесь вы можете получить ссылку на объект ошибки или другие значения, брошенные локальной переменной e
// Кодовый блок здесь может обрабатывать это исключение по какой-то причине или игнорировать это исключение, а также может пересмотреть исключение с помощью оператора Throw
} окончательно{
// Независимо от того, бросает ли оператор TRY исключение, логика, наконец, всегда будет выполнена. Способы прекращения блока операторов try:
// 1. Обычно прекращайте, выполните последний оператор блока оператора
// 2. Закончить с помощью перерыва, продолжения или ответа
// 3. Выбросьте исключение, исключение поймано в пункте «Уловка»
// 4. Выбросить исключение, исключение не поймано, продолжайте распространяться вверх
}
Как правило, поместите весь код, который может добавлять ошибки в блок оператора try, и поместите код, используемый для обработки ошибок в блоке подъема
Если произойдет какой -либо код в ошибке Try Block, процесс выполнения кода будет немедленно выйти, и будет выполнено блок подъема. В настоящее время блок улова получит объект с сообщением об ошибке. Фактическая информация, содержащаяся в этом объекте
[Примечание] Обязательно назовите объект ошибки. Если опустошить его, будет сообщена синтаксическая ошибка.
Кода -копия выглядит следующим образом:
пытаться{
Q;
} catch (error) {
Alert (error.message); // Q не определено
}
// uncaught syntaxError: неожиданный токен)
пытаться{
Q;
}ловить(){
Alert (error.message);
}
Catch принимает параметр, указывающий значение, полученное блоком кода Try
Кода -копия выглядит следующим образом:
функция Throwit (исключение) {
пытаться {
бросить исключение;
} catch (e) {
console.log ('пойман:'+ e);
}
}
Throwit (3); // пойман: 3
Throwit («Привет»); // пойман: привет
Throwit (новая ошибка ('ошибка произошла')); // пойман: ошибка: ошибка произошла
После того, как блок кода подъема поймает ошибку, программа не будет прервана и будет продолжать выполняться в соответствии с обычным процессом.
Кода -копия выглядит следующим образом:
пытаться{
бросить "ошибку";
} catch (e) {
Console.log (111);
}
Console.log (222);
// 111
// 222
Чтобы поймать различные типы ошибок, в блок кода подъема можно добавить операторы суждения
Кода -копия выглядит следующим образом:
пытаться {
foo.bar ();
} catch (e) {
if (e exanterof evelerror) {
console.log (e.name + ":" + e.message);
} else if (e ancementof drangeError) {
console.log (e.name + ":" + e.message);
}
// ...
}
Хотя пункт, наконец, является необязательным в операторе Try-Catch, после использования пункта, наконец, его код будет выполнен, несмотря ни на что. Другими словами, весь код в блоке оператора TRY выполняется нормально, и, наконец, будут выполнены пункты; Если блок оператора Catch будет выполнен из -за ошибки, пункт, наконец, все еще будет выполнен. Пока код содержит, наконец, предложения, независимо от того, какой код содержится в блоке оператора TRY или CALT - или даже оператором возврата, выполнение пункта наконец -то не будет предотвращено.
Кода -копия выглядит следующим образом:
// Ошибка не поймана, потому что нет блока операторов. После выполнения кодового блока наконец -то программа будет прервана при брошении ошибки.
функция чистки () {
пытаться {
бросить новую ошибку ('ошибка ...');
console.log («Эта строка не будет выполнена»);
} окончательно {
console.log («Полная очистка»);
}
}
чистка ();
// завершить уборку
// Ошибка: что -то пошло не так ...
Кода -копия выглядит следующим образом:
function testfinnally () {
пытаться{
возврат 2;
} catch (error) {
возврат 1;
} окончательно{
возврат 0;
}
}
testfinnally (); // 0
[Примечание] Значение подсчета оператора возврата получено до запуска кодового блока, наконец,.
Кода -копия выглядит следующим образом:
var count = 0;
function Countup () {
пытаться {
возврат подсчет;
} окончательно {
count ++;
}
}
countup (); // 0
Console.log (count); // 1
Кода -копия выглядит следующим образом:
функция f () {
пытаться {
console.log (0);
бросить "ошибку";
} catch (e) {
console.log (1);
вернуть истину; // это предложение было бы отложено до окончания кодового блока окончательного кода перед выполнением
Console.log (2); // не будет работать
} окончательно {
console.log (3);
вернуть ложь; // это предложение будет охватывать предыдущий возврат
console.log (4); // не будет работать
}
console.log (5); // не будет работать
}
var result = f ();
// 0
// 1
// 3
console.log (result); // false
【Советы】 Объем на уровне блока
Распространенное использование операторов Try-Catch заключается в создании областей на уровне блока, где объявленные переменные действительны только внутри улова
ES6 представляет ключевое слово let, чтобы создать область на уровне блока для переменных, которые он объявляет. Тем не менее, в текущей ситуации ES3 и ES5 операторы часто используются для достижения аналогичных эффектов
Из следующего кода E существует только в пункте Catch Calce, и при попытке ссылаться на него из других мест.
Кода -копия выглядит следующим образом:
пытаться{
Выбросить новую ошибку (); // превзойти ошибку
} catch (e) {
console.log (e); // ошибка (…)
}
console.log (e); // uncauch referenceerror: e не определено
Общие ошибки
Ядро обработки ошибок - сначала знать, какие ошибки будут произойти в коде. Поскольку JavaScript слабо набран и не проверяет параметры функции, ошибка будет происходить только во время кода. Вообще говоря, необходимо обратить внимание на три типа ошибок: ошибка преобразования, ошибку типа данных и ошибку связи
【Тип ошибка преобразования】
Ошибка преобразования типа возникает при использовании оператора или с использованием другой языковой структуры типов данных, которые могут автоматически преобразовать значения.
Оператор управления потоком склонен к ошибкам преобразования. Заявления, например, если если бы автоматически преобразуют какое -либо значение в логическое, прежде чем определить следующую операцию. Особенно, если утверждения, если они используются неправильно, они, скорее всего, совершат ошибки.
Неиспользуемые именованные переменные автоматически присваиваются неопределенные значения. Неопределенное значение может быть преобразовано в ложно ложно, поэтому оператор IF в следующей функции фактически применим только к случаям, когда предоставляется третий параметр. Проблема в том, что не только неопределенное, чтобы быть преобразованным в FALSE, и не только строковые значения, которые могут быть преобразованы в TRUE. Например, если третий параметр является значением 0, тест оператора if не удастся, а тест логарифмического значения 1 пройдет
Кода -копия выглядит следующим образом:
функция concat (str1, str2, str3) {
var result = str1 + str2;
if (str3) {// абсолютно не так
результат += str3;
}
результат возврата;
}
Использование не-булевых значений в операторах управления потоком является чрезвычайно распространенным источником ошибок. Чтобы избежать таких ошибок, необходимо пройти по логическим значениям при сравнении условий. На самом деле, выполнение какой -то формы сравнения может достичь этого
Кода -копия выглядит следующим образом:
функция concat (str1, str2, str3) {
var result = str1 + str2;
if (typeof str3 == 'string') {// больше подходящего
результат += str3;
}
результат возврата;
}
【Ошибка типа данных】
JavaScript слабо набирается и не будет сравниваться, чтобы убедиться, что их тип данных является правильным до тех пор, пока не будут использоваться переменные и параметры функций. Чтобы убедиться, что ошибки типа данных не возникнут, можно записать только соответствующий код обнаружения типов данных. Ошибки типа данных, скорее всего, возникают при передаче неожиданных значений для построения функций
Кода -копия выглядит следующим образом:
// небезопасные функции, любое значение без арются вызовет ошибки
функция Reversesort (значения) {
if (values) {
values.sort ();
values.reverse ();
}
}
Другая распространенная ошибка - сравнить параметры с нулевыми значениями. Сравнение с NULL только гарантирует, что соответствующие значения не являются нулевыми и неопределенными. Чтобы гарантировать, что передаваемое значение действительнее, этого недостаточно, чтобы обнаружить только нулевые значения
Кода -копия выглядит следующим образом:
// небезопасные функции, любое значение без арются вызовет ошибки
функция Reversesort (значения) {
if (values! = null) {
values.sort ();
values.reverse ();
}
}
Если объект, содержащий метод sort () (а не массив), пройден, он пройдет обнаружение, но при вызове функции обратного () может возникнуть ошибка.
Кода -копия выглядит следующим образом:
// небезопасные функции, любое значение без арются вызовет ошибки
функция Reversesort (значения) {
if (typeof values.sort == 'function') {
values.sort ();
values.reverse ();
}
}
Если вы точно знаете, какой тип вы должны пройти, лучше всего использовать экземпляр для обнаружения типа данных
Кода -копия выглядит следующим образом:
// безопасные, не обращаются
функция Reversesort (значения) {
if (значения экземпляра массива) {
values.sort ();
values.reverse ();
}
}
【Ошибка связи】
С ростом программирования AJAX для веб -приложений стало обычным явлением для динамической загрузки информации или функциональности в течение их жизненного цикла. Однако любая связь между JavaScript и сервером может вызвать ошибку
Наиболее распространенной проблемой является то, что данные не кодируются с использованием encodeuricomponent () перед отправкой на сервер
Кода -копия выглядит следующим образом:
//ошибка
http://www.yourdomain.com/?redir=http://www.sometherdomain.com?a=b&c=d
// Вызов encodeuricomponent () для всех строк после «redir =» может решить эту проблему
http://www.yourdomain