JavaScript 异常(例外)处理

阅读目录

1. 错误VS异常
2. 术语:JS抛出错误
3. JS异常类型
3.1 代码错误
3.2 运行错误
4. JS异常的载体
4.1 Error对象
4.2 Error的子类(6)
5. JS异常捕获(监控)方法
5.1 window.onerror
5.2 try…catch…finally中的catch
5.3 二者区别
6. JS异常处理方法
6.1 定义
6.2 优点
6.3 try…catch…finally方法

1. 错误VS异常

错误(error):
A)非正常的系统级的严重错误,出现后程序直接终止的,为不可预见的;
B)程序运行时不满足某些条件而出现非严重错误,即异常(exception)。

2. 术语:JS抛出错误

JS抛出错误:俗称“报错”,即当错误发生时,当事情出问题时,JavaScript 引擎通常会停止,并生成一个错误消息。

3. JS异常类型

3.1 代码(编译)错误
A)语法错误(SyntaxError):
eg:拼写错误。
该错误下,浏览器会直接报错,整个代码都不会执行。
B)范围错误(RangeError):
该错误下,错误之前的代码会执行,之后代码不会执行。
C)引用错误(ReferenceError):
该错误下,错误之前的代码会执行,之后代码不会执行。
D)类型错误(TypeError):
该错误下,错误之前的代码会执行,之后代码不会执行。

3.2 运行错误:
A)运行错误(runtime error):
eg:系统资源不可用(内存分配失败,文件打开失败,数据库打开失败等)
B)逻辑错误(bug):
eg:程序控制不当(除数为0;负数开方等)

4. JS异常的载体

4.1 Error对象
name属性表示例外的类型;
message属性表示例外的含义。
4.2 Error的子类(6)
A)Error:基类型。即:所有的错误都继承该类型。提供这个基类型的主要目的是提供给开发人员抛出自定义的错误。
eg:throw new Error(输出错误信息)。

B)SyntaxError:语法错误。即:解析错误。
eg:var 1a;
显示:Uncaught SyntaxError: Unexpected number

C)RangeError: 范围错误。即:数字超出有效范围会抛出该错误。
eg:var a= new Array(-1);
显示:Uncaught RangeError: Invalid array length

D)ReferenceError:引用错误。即:在找不到对象会抛出错误。
a)引用了一个不存在的变量
eg: console.log(a);
显示:Uncaught ReferenceError: a is not defined
b)将变量赋值给一个无法被赋值的对象
eg:console.log()= 1;
显示:Uncaught ReferenceError: Invalid left-hand side in assignment

E)TypeError:类型错误。通常在if控制流中和全等,相等的比较中存在类型转换。
a)变量或参数不是预期类型,比如,对字符串、布尔值、数值等原始类型的值使用new命令,就会抛出这种错误,因为new命令的参数应该是一个构造函数。
eg: var a= new 123;
显示:Uncaught TypeError: 123 is not a function
b)调用对象不存在的方法
eg:var a;a.aa();
显示:Uncaught TypeError: Cannot read property ‘aa’ of undefined

F)EvalError:eval错误。即:未恰当使用eval()函数会抛出该错误。例如未将eval当作函数使用。
eg:new eval()。

G)URLError:url错误。即:使用与url相关函数参数不正确。
主要是encodeURI()、decodeURI()、encodeURIComponent()、decodeURIComponent()、escape()和unescape()这六个函数。这种类型不常见。
eg: decodeURI(’%2’)
显示:Uncaught URIError: URI malformed

5. JS异常捕获(监控)方法

5.1 window.onerror

  windowonerror = function(message, source, lineno, colno, error) { ... }
    message: Uncaught ReferenceError: test is not defined //异常基本信息
    source:  http://test.com/release/attach.js            //发生异常Javascript文件url
    lineno:  16144                                        //发生错误的行号
    colno:   6
    error:   ReferenceError: test is not defined
                at http://test.com/release/attach.js:16144:6
                at HTMLDocument.<anonymous> (http://test.com/release/vendor.js:654:71) // error.stack获取异常的堆栈信息

5.2 try…catch…finally中的“catch”

 try{
        ...    //异常的抛出
 }
 catch(e){
        ...    //异常的捕获与处理
 }
 finally{
        ...    //结束处理
 }

5.3 二者区别
window.onerror
优点:全局监控
缺点:兼容性问题导致不一定拿到出错信息,有些浏览器出于安全方面的考虑,对于不同域的Javascript文件,通过window.onError无法获取有效的错误信息。
eg:firefox的错误消息只有Script error,而且无法获得确切的行号,更没有错误堆栈信息。
try…catch…finally
优点:可拿到出错信息
缺点:局部监控,无法监控语法错误,仅监控运行错误。

6. JS异常处理方法(例外处理)

6.1 定义
当JavaScript程序在运行中发生了诸如数组索引越界、类型不匹配或者语法错误时,JavaScript解释器就会引发例外处理(exception handlers)。
6.2 优点
通过运用例外处理技术,我们可以实现用结构化的方式来响应错误事件的发生,让例外处理代码与正常脚本代码科学分离,最终使我们能够集中精力编写完成主要功能的核心程序。
6.3 try…catch…finally方法
A)基本语法

try{
    ...    //异常的抛出
}
catch(e){
    ...    //异常的捕获与处理
}
finally{
    ...    //结束处理
}

首先执行try块中的语句,如果运行中发生了错误,控制就会转移到位于catch块中语句。
其中括号中的error参数被作为例外变量传递。
否则,catch块的语句被跳过不执行。
无论是发生错误时catch块中的语句执行完毕,或者没有发生错误try块中的语句执行完毕,最后将执行finally块中的语句。

B)捕获内容
a)js原生错误类型的例外(Error6子类)


     <!DOCTYPE html>
        <html lang="en">
        <head>
        	<meta charset="UTF-8">
        	<title>exception handlers-error</title>
        	<script>
        		var txt = "";
        		function message(){
        			try{
        				var x = document.getElementById("demo").value;
        			}
        			catch(e){  
        				// \n\n表示换行  +=:=用于赋值,+用于加值。
        				//x+=y等价于x=x+y。
                        txt+= "Error description:"+ e.message + "\n\n";
                        //错误表述为
                        //Uncaught TypeError: 类型错误
        				//Cannot read property 'value' of null未能找到demo值
                        txt+= "Click OK to continue.\n\n";
                        //点击确认继续
                        //alert()方法:显示制定消息与一个OK按钮警告框。
                        alert(txt);
        			}
        			finally{
        		    	var z=document.getElementById("msg");
        		    	z.innerHTML="have fun.";
        		    }
        		}
        	</script>
        </head>
        <body>
        	<input type="button" value="View message" onclick="message()">
        	<p id="msg"></p>
        </body>
        </html>

b)执行throw语句产生的例外(throw自定义错误)


    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<title>exception handlers-throw</title>
    	<script>
    		function myFunction(){
    		   try{
    				var x=document.getElementById("demo").value;
    				if(x=="")    throw "empty";
    				if(isNaN(x)) throw "not a number";
    				if(x>10)     throw "too large";
    				if(x<5)      throw "too small";
    		    }
    		    catch(err){
    				var y=document.getElementById("mess");
    				y.innerHTML="Error: " + err + ".";
    		    }
    		    finally{
    		    	var z=document.getElementById("msg");
    		    	z.innerHTML="have fun.";
    		    }
    		}
    </script>
    </head>
    <body>
    	<p>Please input a number between 5 and 10:</p>
    	<input id="demo" type="text">
    	<button type="button" onclick="myFunction()">Test Input</button>
    	<p id="mess"></p>
    	<p id="msg"></p>
    </body>
    </html>

C)捕获方式
a)条件捕获catch(e instanceof obj)
用 instanceof 判断异常的对象类型,实现指定的异常处理方式。

    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<title>条件捕获</title>
    	<script>
    		var txt = "";
    		function myfunction(){
    			try{
    				// new Array(-1);
    				// decodeURI('%2');
    				var x = document.getElementById("demo").value;
    				//执行顺序:要么RangeError,要么URIError,要么TypeError,要么else,4选1。
    			}
    			catch(e) {
    				if (e instanceof RangeError) {
    					alert(e.name + "是" + e.message);
    				}
    				else if (e instanceof URIError) {
    					alert(e.name + "为" + e.message);
    				}
    				else if (e instanceof TypeError) {
    					alert(e.name + ":" + e.message);
    				} 
    				else{
    					txt += "All error:"+ e.message;
    				    alert(txt);
    				}	
    			}
    		} 
    	</script>
    </head>
    <body>
    	<input type="button" value="View myfunction" onclick="myfunction()">
    </body>
    </html>

b)非条件捕获catch(e)
当异常抛出时,无论异常的类型都进行捕获并处理。

    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<title>非条件捕获</title>
    	<script>
    		var txt = "";
    		function myfunction(){
    			try{
    				// new Array(-1);
    				// decodeURI('%2');
    				//无论哪种错误都会捕获;
    				var x = document.getElementById("demo").value;
    			}		
    			catch(e) {
    					txt += "All error:"+ e.message;
    				    alert(txt);
    		    }	
    		} 
    	</script>
    </head>
    <body>
    	<input type="button" value="View myfunction" onclick="myfunction()">
    </body>
    </html>

注:

  1. 如果条件捕获和非条件捕获共用,那么非条件捕获必须放在最后,因为它是无条件的捕获类型,捕获后会忽略后面的任意 catch 块。
  2. 对异常的处理必须考虑周全,在 catch 里要么处理所有的异常,要么再次抛出异常(假定外层还有异常处理),否则在调试过程中会非常困难,因为出现的异常被忽略了。

D)变形
a)try…catch结构
当没有例外发生执行完毕try块语句后或者发生例外执行完catch块语句后,控制将转移到整个try…catch结构后面的语句。

<!DOCTYPE html>
        <html lang="en">
        <head>
        	<meta charset="UTF-8">
        	<title>try...catch</title>
        	<script>
                try {
        	     	document.writeln("Beginnng the try block" + "<br>");
        			var x = document.getElementById("demo").value;
        			document.writeln("Finished the try block with no exceptions")
        		} 
                catch(err) {
        	    document.writeln("错误: " + err.name + "<br>")
        	    document.writeln("错误内容: " + err.message  + "<br>") 
        	  }
              document.writeln("Executing after the try-catch statement" + "<br>")
        	</script>
        </head>
        <body>
        </body>
        </html>

b)try…finally结构
当执行完毕try块语句后无论有无例外,控制将转移到finally语句,这种结构在实际应用中很少见。

    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<title>try...finally</title>
    	<script>
            try {
    	     	document.writeln("Beginnng the try block" + "<br>");
    			var x = document.getElementById("demo").value;
    			document.writeln("Finished the try block with no exceptions")
    		} 
          finally{
    	        document.writeln("Executing after the try-catch statement" + "<br>")
    	    }
    	</script>
    </head>
    <body>
    </body>
    </html>

E)嵌套例外处理
JavaScript支持多层次的嵌套例外处理。一般情况下,我们可以在内部例外处理的catch代码块中捕捉并处理错误,然后再次触发例外,这样就可进一步在外部例外处理的catch代码块中做更加深入的处理。
优点:能够很好地分阶段处理错误,内部例外处理可以负责解决由错误引发的脚本代码问题,外部例外处理则用于负责提供给用户的反馈信息或者对例外信息进行日志记录。

    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<title>嵌套例外处理</title>
    	<script>
    		var inner;
    		var outer;
    		try {
    		  document.writeln("Beginning outer try block, no exceptions yet" + "<br>");
    		    try {
    			   document.writeln("Beginning inner try block, no exceptions yet" + "<br>");
    			    // 生成一个引用错误
    			    document.writeln(undefinedVariable)
    			    document.writeln("Finished inner try block with no exceptions"  + "<br>");
    			} 
    			catch(inner) {
    			   // 内部例外处理
                   document.writeln("Exception caught, beginning inner catch block" + "<br>");
    			  document.writeln("错误类型: " + inner.name + "<br>");
    			  document.writeln("错误信息: " + inner.message + "<br>");
    			  throw inner;
    			  document.writeln("No exceptions thrown in inner catch block" + "<br>");
    			} 
    			finally {
    			  document.writeln("Executing inner finally block" + "<br>");
    			}
    			  document.writeln("Finished outer try block with no exceptions" + "<br>");
    		} 
    		catch(outer) {
    		  // 外部例外处理
    		   document.writeln("Exception caught, beginning outer catch block" + "<br>");
    		  document.writeln("Error type: " + outer.name + "<br>");
    		  document.writeln("Error message: " + outer.message + "<br>");
    		} 
    		finally {
    		  document.writeln("Executing outer finally block" + "<br>");
    		}
    	</script>
    </head>
    <body>
    </body>
    </html>

参考文献:
https://blog.csdn.net/sdta25196/article/details/78841666
https://www.cnblogs.com/luluping/archive/2011/02/14/1954092.html
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error
http://sh.qihoo.com/pc/9d838f51991389a94?sign=360_e39369d1
https://www.haorooms.com/post/js_qd_error等

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值