JavaScript之异常捕获

今天学习了异常捕获,分享一下学到的东西:

1.什么是异常捕获?

  在JS代码平常的运行中,因为单线程的缘故,上面的代码和下面的代码都是“一根绳上的蚂蚱”,如果上面的代码出了问题,下面的代码则不会执行,所以我们需要捕获到异常并对接下来的事情进行处理。

2.怎么捕获呢?

  因为JavaScript的语法是从Java继承而来的,Java的异常捕获语法自然也被它拿了过来,在以前,如果要处理异常,可能需要写一堆的if...else语句来对程序的情况进行判断,尽量避免异常。不过现在已经引入了新的语句,那么异常处理起来也就不是那么难了。

  throw:

          throw的语法throw <something>

   这里的<something>可以是任意的JavaScript值,Number,String,Array,Object都可以,为了简单起见,之前会有很多JavaScript代码这样写:

1 if(abnormalHappened){
2     throw 'Abnormal!';           
3 }

   这样看起来也太随意了,不要这样子写。在JavaScript中提供了专门用于异常处理的对象,修改之后:

if(abnormalHappened){
    throw new Error('Abnormal!');  
}
//有什么好处?
//大多数JavaScript引擎会自动加上栈追踪,并且错误对象会提供更丰富的上下文信息
//回过头来再看光扔出来个字符串,是不是Low爆了

 

    try-catch-finally:

      语法:

        try{
          //代码块1..
        }catch{
          //代码块2..
        }finally{

          //代码块3..

        }

      [try语句必须有,catch和finally语句起码得有1个]

  工作原理:将可能出现异常的代码放进try语句块中,将处理异常的代码放进catch语句块中,finally语句块中放一些做后期清理工作的代码。catch会捕获到try语句块中的抛出的任何异常,无论try语句块中啥都没发生也好,发生了异常也好,finally语句块最终都会执行。

      

 1 function throwSth(sth){
 2     try{
 3         throw sth; //这里throw出去的东西将会被catch接收到      
 4     } catch(err){
 5         console.log('Have caught: ' + err);
 6     }
 7 }
 8 
 9 throwSth(3);  // -> Have caught: 3
10 throwSth('HelloWorld');  // -> Have caught: 'HelloWorld'
11 throwSth(new Error('An error'));  // -> Have caught: Error: An error

 

 

    这里来看一下finally的用法:

 1 (function() {
 2     try {
 3         throw new Error('No!Here is an error!');
 4     } finally {
 5         console.log('I still run~');
 6     }
 7 })();
 8 
 9 /* 
10     I still run~
11     VM600:3 Uncaught Error: No!Here is an error!
12         at <anonymous>:3:15
13         at <anonymous>:7:3
14 */

  这里可以看出,即使try里面抛出了错误,finally还是照常执行了出来,说明finally不受到其它语句块的影响,会厚着脸皮执行下去。

3.Error构造器

  ECMAScript标准化了以下错误构造函数。

  • Error "通用异常构造器"  所有其他的异常构造器都是它的子构造器。
  • RangeError "表示一个数值超出了它被允许的范围"
  • ReferenceError "表示发现了一个非法的引用值"
  • SyntaxError "表示产生了一个语法解析错误"
  • TypeError "表示一个被操作值的实际类型与其期望的类型不一致"
  • URIError "表示某个全局的URI控制函数的使用不兼容其定义"

  异常的属性值:

  • message: 异常的信息
  • name: 异常的名称
  • Stack: 栈跟踪。它不是标准的,但很多平台都在使用。例如,Chrome、Node.js和Firefox

4.栈跟踪

  通常,异常大多数来自于代码的异常(自作孽的bug),少部分来自于外部(错误的输入、无法找到文件等等)。JavaScript提供的debugger只能增加一个断点,但并没有提供bug的详细信息,我们一般来说需要获取错误的两种信息:

  1.错误类型:是什么类型的错误?是语法错了?还是我的变量定义出了问题?

  2.错误位置:异常发生在哪一行?

  所以通过栈跟踪,或创建异常对象的调用栈快照。下面的例子会输出一个调用栈:

    

 1 (function() {
 2     try {
 3         throw new Error('An Error');    
 4     } catch(err) {
 5         console.log(err.stack);
 6     }
 7 })();
 8 
 9 /*
10    Error: An Error
11     at pro3.html:52
12     at pro3.html:56 
13 */

  这就很舒服了,它不仅给出了错误的信息,还给出了错误发生的位置,上面显示了代码中抛出错误的位置。

  以上很多内容来自于我进行学习的资料 --- 《深入理解JavaScript》

  总结了今天自己学的,欢迎大家在讨论区提问讨论。