JavaScript基础——错误处理与测试

来源:互联网 发布:linux怎么关闭tomcat 编辑:程序博客网 时间:2024/06/07 05:32

错误处理对于今天复杂的Web应用程序开发而言至关重要。

不能提前预测到可能发生的错误,不能提前采取回复策略,可能导致较差的用户体验,最终引发用户不满。

多数浏览器在默认情况下都不会向用户报告错误,因此在开发和调试期间需要启动浏览器的错误报告功能。

然而,在投入运行的产品代码中,则不应该再有诸如此类的错误报告出现。

下面是几种避免浏览器响应JavaScript错误的方法。

1)在可能发生错误的地方使用try-catch语句,这样你还有机会以适当的方式对错误给出响应,而不必沿用浏览器处理错误的机制;

2)使用window.onerror事件处理程序,这种方式可以接受try-catch不能处理的所有错误(仅限于IE、Firefox和Chrome)。

另外,对于Web应用程序都应该分析可能的错误来源,并制定处理错误的方案。

1)首先,必须要明确什么是致命错误,什么是非致命错误;

2)其次,再分析代码,以判断最可能发生的错误。JavaScript中发生错误的主要原因如下:

   2.1)类型转换

   2.2)未充分检测数据类型

   2.3)发送给服务器或从服务器接收到的数据有错误

IE、Firefox、Chrome、Opera和Safari都有JavaScript调试器,有的是内置的,有的是以需要下载的扩展形式存在的。这些调试器都支持设置断点、控制代码执行及在运行时检测变量的值。

/** *错误处理与调试 */function cl(x){    console.log(x);}/** * 17.1 浏览器报告的错误 *///17.1.1 IE:工具——Internet选项——高级——显示每个脚本错误的通知//17.1.2 Firefox:Firebug//17.1.3 Safari:编辑——偏好设置——高级——在惨淡兰中显示"开发"菜单//17.1.4 Opera//17.1.5 Chrome:开发者工具栏/** * 17.2 错误处理 *///17.2.1 try-catch语句//错误消息的message属性//17.2.1.1 finally子句//17.2.1.2 错误类型//Error、EvalError、RangeError、ReferenceError、SyntaxError、TypeError、URIError//17.2.1.3 合理使用try-catch//17.2.2 抛出错误//通过原型链可以通过继承Error来创建自定义错误类型function CustomError(message){    this.name="CustomError";    this.message=message;}CustomError.prototype=new Error();//throw new CustomError("我错了");//17.2.2.1 抛出错误的时机function process(values){    //自定义错误:参数不是数组则抛出异常    if(!(values instanceof Array)){        throw new Error("process():参数必须是数组类型");    }    values.sort();    for(var i= 0,len=values.length;i<len;i++){        if(values[i]>100){            return values[i];        }    }    return -1;}//17.2.2.2 抛出错误与使用try-catch//捕获错误的目的在于避免浏览器以默认方式处理它们;//而抛出错误的目的在于提供错误发生具体原因的消息。//17.2.3 错误(error)事件window.onerror=function(message,url,line){    alert(message);    return false;}//图像也支持error事件var image=new Image();image.onload=function(event){    alert("图像加载了");}image.onerror=function(event){    alert("图像没有加载");}image.src="sim.gif";//17.2.4 处理错误的策略//17.2.5 常见的错误类型//17.2.5.1 类型转换错误//建议使用全等(===)和不全等(!==)操作符,以避免类型转换//在流控制语句中,在条件比较时切实传入布尔值,可以避免类型转换错误function concat(str1,str2,str3){    var result=str1+str2;    if(typeof str3=="string"){        result+=str3;    }    return result;}//17.2.5.2 数据类型错误//基本类型的值应该使用typeof来检测//对象的值应该使用instanceof来检测//例:获取一个url的?后的字符串function getQueryString(url){    if(typeof url=="string"){//通过检查类型确保安全        var pos=url.indexOf("?");        if(pos>-1){            return url.substring(pos+1);        }    }    return "";}//例:将一个数组反向排序function reverseSort(values){    if(values instanceof Array){//非数组值将被忽略        values.sort();        values.reverse();    }}//17.2.5.3 通信错误//处理查询字符串的函数function addQueryStringArg(url,name,value){    if(url.indexOf("?")==-1){        url+="?";    }else{        url+="&"    }    url+=encodeURIComponent(name)+"="+encodeURIComponent(value);    return url;}var url="http://www.baidu.com";var newUrl=addQueryStringArg(url,"redir","http://www.sportsbaidu.com?a=b&c=d");alert(newUrl);//17.2.6 区分致命错误和非致命错误//例:把所有模块的错误变成非致命的var mods=[error1,error2,error3];for(var i= 0,len=mods.length;i<len;i++){    try{        mods[i].init();    }catch(ex){        //处理错误    }}//17.2.7 把错误记录到服务器//类似以下函数从查询字符串中取得数据function logError(sev,msg){    var img=new Image();    img.src="log.php?sev="+encodeURIComponent(sev)+"&msg="+encodeURIComponent(msg);}//使用try-catch语句,把相应错误记录到日志中for(var i= 0,len=mods.length;i<len;i++){    try{        mods[i].init();    }catch(ex){        logError("nonfatal","Module init failed:"+ex.message);    }}/** * 17.3 调试技术 *///17.3.1 将消息记录到控制台//console对象有下列方法:error(msg)、info(msg)、log(msg)、warn(msg)//不存在一种跨浏览器向JavaScript控制台写入消息的机制,但下面的函数可以作为统一的接口function log(message){    if(typeof console=="object"){        console.log(message);    }else if(typeof opera=="object"){        opera.postError(message);    }else if(typeof java=="object" && typeof java.lang=="object"){        java.lang.System.out.println(message);    }}function sum(num1,num2){    log("传入的参数是:"+num1+","+num2);    log("开始记录错误:");    var result=num1+num2;    log("结束记录错误");    return result;}//17.3.2 将消息记录到当前页面//17.3.3 抛出错误//如果错误消息很具体,可抛出错误信息function divide1(num1,num2){    if(typeof num1!="number" || typeof num2 !="number"){        throw new Error("divide1():两个参数必须都是数字");    }    return num1/num2;}function assert(condition,message){    if(!condition){        throw new Error(message);    }}//对于大型应用程序来说,自定义的错误通常使用assert()函数抛出function divide2(num1,num2){    assert(typeof num1=="number" && typeof num2=="number",    "divide2():两个参数必须都是数字");    return num1/num2;}/** * 17.4 常见的IE错误 *///17.4.1 操作终止//17.4.2 无效字符//17.4.3 未找到成员document.onclick=function(){    var event=window.event;    setTimeout(function(){        event.returnValue=false;//未找到成员错误    },1000);};//17.4.4 未知运行时错误//当使用innerHTML或outerHTML以下列方式指定HTML时,就会发生未知运行时错误://一是把块元素插入到行内元素时,二是访问表格任意部分的任意属性时//17.4.5 语法错误//17.4.6 系统无法找到指定资源



0 0
原创粉丝点击