Шрифт:
'Msxml2.XMLHTTP.3.0', 'Msxml2.XMLHTTP', 'Microsoft.XMLHTTP'];
for(var i=0; i<activeXObjects.length; i++){
try{
return new ActiveXObject(activeXObjects[i]);
}catch(err){}
}
Заранее неизвестно, какие объекты установил пользователь, и, к сожалению, браузер не предоставляет никакого механизма это определить. Поэтому остается создавать каждый из 6 возможных объектов, пока один из них (будем надеяться) не заработает.
Операторы Try/Catch можно использовать для перехвата ошибок двух типов: ошибок времени выполнения и ошибок пользователя. Ошибки времени выполнения, как говорилось ранее, возникают, когда у компилятора JavaScript существует проблема с созданным кодом. Ошибки пользователя, с другой стороны, будут технически проходить без проблем, но возникают в связи с контекстом приложения. Если имеется поле, в которое пользователь, например, должен ввести свой возраст, и пользователь вводит – 2, то это приводит к появлению ошибки.
Блок Try/Catch имеет достаточно простой синтаксис:
try{
// код
}catch(err){
// код обработки ошибки
}
Если код в блоке try приводит к ошибке, то сценарий немедленно переходит в блок catch. Объект ошибки err в JavaScript имеет ряд полезных свойств - описание, сообщение, имя и номер, которые можно использовать для вывода информации о том, что произошло:
try{
var x;
x[5] = 5;
}catch(err){
alert('An error occured: '+err.description);
}
Если в операторе catch окажется ошибка, то JavaScript сможет обратиться в дальнейшем к ее описанию.
Такой блок кода Try/Catch можно применять в любом месте. Однако, обычно, код должен быть написан таким образом, чтобы это не нужно было использовать, - в частности, весь ввод должен проверяться.
Блок Try/Catch можно применять также для создания своих собственных ошибок:
function setAge(x){
if(typeof(x)=='undefined') throw('Вы должны ввести возраст');
if(typeof(x)!='number') throw('Возраст должен быть числом');
if(x<0) throw('Возраст не может быть меньше 0');
if(x>120) throw('Возраст не может быть больше 120');
var myAge = x;
// еще код
}
try{
setAge(userInput);
}catch(err){
alert(err);
}
В этом случае выполняется проверка того, что пользователь вводит возраст. Если он вводит недопустимые данные, сценарий немедленно завершается, а пользователь получает сообщение об ошибке.
Блок try/catch имеет еще одну часть, оператор finally:
try{
// код
}catch(err){
// код
}finally{
// код
}
Код в "завершающем блоке" будет выполняться независимо от того, что происходит с операторами Try/Catch. В чем же разница между завершающим блоком и простым размещением кода после блока try/catch? В большинстве случаев никакой разницы не будет. Однако, если блок try/catch находится в функции и происходит выход из функции в блоке try или catch, то возникнет существенное различие:
function myFunction{
try{
return someValue;
}catch(err){
return defaultValue;
}finally{
alert('finally!');
}
alert('End!');
}
В этом случае оба блока try и catch возвращают значение. Мы получим сообщение "finally!", но не получим сообщение "End!", потому что произойдет выход из функции до сообщения alert('End!'). То же самое остается справедливым для операторов Try/Catch, которые осуществляют выход из тела цикла for или while, например:
for(var i=0; i<10; i++){
try{
if(i==5) continue;
}catch(err){
// обработка ошибки
}finally{
// код
}
// еще код
}
Запросы XMLHttp, рассмотренные в предыдущей лекции, могут иметь совершенно другой тип ошибки: данные просто не проходят. Это можно проверить через статус объекта XMLHttp:
function processingFunction{
if(oXml.readyState!=4) return; // запрос не выполнен
switch(oXml.status){
case 0: case 200: // запрос выполнен
break;
case 408: case 504: // запрос превысил время ожидания
// код
break;
default: // ошибка запроса
// код
return; // возможно, вы захотите выйти
break;
}
// продолжение обработки запроса
}
oXml в этом примере является объектом XMLHttp, а функция processingFunction была присоединена к свойству onreadystatechange этого объекта.