try-catch语句

try{
    //可能会导致错误的代码
}catch(error){
    //在错误发生时怎么处理
}

如果try块中的任何代码发生了错误,就会立即退出代码执行过程,然后接着执行catch块。此时,catch块会接收到一个包含错误信息到对象。与其他语言中不同到是,
即使你不想使用这个错误对象,也要给他起个名字。

try{
    window.someNonexistentFunction();
}catch(error){
    console.log(error.message);
}

 

finally

function testFinally(){
    try{
        return 2;
    }catch(error){
        return 1;
    }finally{
        return 0;
    }
}

只要代码中包含finally子句,那么无论try还是catch语句块中的return语句都将被忽略。因此,在使用finally子句之前,一定要非常清楚你想让代码怎么样。


错误类型
ECMA-262定义了7种错误类型: Error, EvalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError
1)、Error
Error是基类型,其他错误类型都继承自该类型,Error类型都错误很少见,如果有也是浏览器抛出的;这个基类型的主要目的是提供开发人员抛出自定义错误
2)、EvalError

new eval(); //TypeError: eval is not a constructor

EvalError不再会被JavaScript抛出,但是EvalError对象仍然保持兼容性.有鉴于此,加上实际开发中很少使用eval(),所以遇到这种错误类型的可能性极小。
3)、RangeError

var items1 = new Array(-20); // RangeError: Invalid array length
var items2 = new Array(Number.MAX_VALUE); //RangeError: Invalid array length

RangeError类型的错误会在数值超出相应范围触发。例如,在定义数组是,指定了数组不支持的项数
4)、ReferenceError

var obj = x; //ReferenceError: x is not defined
eval = foo; // ReferenceError: foo is not defined

在找不到对象的情况下,会发生ReferenceError,通常,在访问不存在的变量时,就会发生这种错误
5)、SyntaxError

eval('a ++ b'); //SyntaxError: Unexpected identifier

当我们把语法错误的js字符传入eval()函数时,就会导致此类错误。如果语法错误的代码出现在eval()函数之外,则不太可能使用SyntaxError。
6)、TypeError

var o = new 10; //TypeError: 10 is not a constructor
console.log('name' is true); //TypeError: Cannot use 'in' operator to search for 'name' in true
Function.prototype.toString.call('name'); //TypeError: Function.prototype.toString requires that 'this' be a Function

TypeError类型在js中会经常用到,在变量中保存着意外的类型,或者访问不存在的方法时,都会导致这种错误,错误的原因多种多样,但归根结底还是由于在执行
特定类型的操作时,变量的类型并不符合要求所致。
7)、URIError
在使用encodeURI()或decodeURI(),而URI格式不正确时,就是导致URIError错误。这种错误也很少见,因为前面说的这个两个函数的容错性非常高。

8)、要想知道错误的类型,可以像下面这样处理

try{
    someFunction()
}catch(error){
    if(error instanceof TypeError){
        console.log('处理类型错误');
    }else if(error instanceof ReferenceError){
        console.log('处理引用错误');
    }else{
        console.log('处理其他类型的错误');
    }
}

9)、合理使用try-catch
使用try-catch最适合处理那些我们无法控制的错误。假设你在使用大型js库中的函数,该函数可能会有意无意地抛出一些错误。由于我们不能修改这个库的源代码,所以大可
将该函数的调用放在try-catch语句当中,万一有什么错误时,也好恰当地处理
在明明白白地知道自己地代码会发生错误,再使用try-catch语句就不太合适了。例如,如果传递给函数地参数时字符串而非树枝,就会造成函数出错,那么就应该检查参数地类型,
然后再决定如何去做。


抛出错误
在遇到throw操作符时,代码会立即停止执行。仅当有try-catch语句捕获被抛出的值时,代码才会继续执行

function process(values){
    values.sort();
    for(var i=0; i<values.length; i<len; i++){
        if(values[i] > 100){
            return values[i];
        }
    }
    return -1;
}

如果执行这个函数时传给它一个字符串参数,那么对sort()对调用就会失败。对此,不同对浏览器会给出不同对错误消息,但都不是特别明确。这个情况下,带有适当的
自定义错误能够显著提升代码的可维护性。

function process(values){
    if(!(values instanceof Array)){
        throw new Error("process(): Argument must be an array");
    }
    values.sort();
    for(var i=0; i<values.length; i<len; i++){
        if(values[i] > 100){
            return values[i];
        }
    }
    return -1;
} 

建议读者在开发javascript代码的过程中,重点关注函数和可能导致函数执行失败的因素。良好的错误处理机制应该可以确保代码中只发生你自己抛出的错误。

 

error事件
任何没有通过try-catch处理的错误都会触发window对象的error事件。这个事件时web浏览器最早支持的事件之一。

window.onerror = function(message, url, line){
    console.log(message);
}

只要发生错误,无论是不是浏览器生成的,都会触发error事件,并执行这个事件处理程序。