前端基础笔记

【javascript】错误处理和调试

2018-01-04  本文已影响3人  shanruopeng

1、错误处理

1.1 try-catch语句

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

(1)finally 子句

function testFinally(){
    try {
        return 2;
    } catch (error){
        return 1;
    } finally {
        return 0;
    }
}
/**调用这个函数只能返回0**/

(2)错误类型

new eval(); //抛出EvalError
eval = foo; //抛出EvalError
var items1 = new Array(-20); //抛出RangeError
var items2 = new Array(Number.MAX_VALUE); //抛出RangeError
var obj = x; //在x 并未声明的情况下抛出 ReferenceError
eval("a ++ b"); //抛出SyntaxError
var o = new 10; //抛出TypeError
alert("name" in true); //抛出TypeError
Function.prototype.toString.call("name"); //抛出TypeError
try {
    someFunction();
} catch (error){
    if (error instanceof TypeError){
        //处理类型错误
    } else if (error instanceof ReferenceError){
        //处理引用错误
    } else {
        //处理其他类型的错误
    }
}

(3)合理使用try-catch

1.2 抛出错误

function CustomError(message){
    this.name = "CustomError";
    this.message = message;
}
CustomError.prototype = new Error();
throw new CustomError("My message");

(1)抛出错误的时机

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

(2) 抛出错误与使用try-catch

1.3 错误事件

window.onerror = function(message, url, line){
    alert(message);
    //阻止浏览器报告错误的默认行为。
    return false;
};

1.4 常见的错误类型

(1)类型转换错误

function concat(str1, str2, str3){
    var result = str1 + str2;
    if (str3){ //绝对不要这样!!!
        result += str3;
    }
    return result;
}

function concat(str1, str2, str3){
    var result = str1 + str2;
    if (typeof str3 == "string"){ //恰当的比较
        result += str3;
    }
    return result;
}

(2) 数据类型错误


/**例子一**/

//不安全的函数,任何非字符串值都会导致错误
function getQueryString(url){
    var pos = url.indexOf("?");
    if (pos > -1){
        return url.substring(pos +1);
    }
    return "";
}

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){ //绝对不要这样!!!
        values.sort();
        values.reverse();
    }
}

//不安全的函数,任何非数组值都会导致错误
function reverseSort(values){
    if (values != null){ //绝对不要这样!!!
        values.sort();
        values.reverse();
    }
}

//还是不安全,任何非数组值都会导致错误
function reverseSort(values){
    if (typeof values.sort == "function"){ //绝对不要这样!!!
        values.sort();
        values.reverse();
    }
}

//安全,非数组值将被忽略
function reverseSort(values){
    if (values instanceof Array){ //问题解决了
        values.sort();
        values.reverse();
    }
}

(3)通信错误

function addQueryStringArg(url, name, value){
    if (url.indexOf("?") == -1){
        url += "?";
    } else {
        url += "&";
    }
    url += encodeURIComponent(name) + "=" + encodeURIComponent(value);
    return url;
}

1.5 区分致命错误和非致命错误

for (var i=0, len=mods.length; i < len; i++){
    mods[i].init(); //可能会导致致命错误
}

for (var i=0, len=mods.length; i < len; i++){
    try {
        mods[i].init();
    } catch (ex) {
        //在这里处理错误
    }
}

1.6 把错误记录到服务器

function logError(sev, msg){
    var img = new Image();
    img.src = "log.php?sev=" + encodeURIComponent(sev) + "&msg=" +
    encodeURIComponent(msg);
}

for (var i=0, len=mods.length; i < len; i++){
    try {
        mods[i].init();
    } catch (ex){
        logError("nonfatal", "Module init failed: " + ex.message);
    }
}

2、调试技术

(1)将消息记录到控制台

(2)将消息记录到当前页面

(3)抛出错误

function divide(num1, num2){
    if (typeof num1 != "number" || typeof num2 != "number"){
        throw new Error("divide(): Both arguments must be numbers.");
    }
    return num1 / num2;
}
//基本的assert()函数
function assert(condition, message){
    if (!condition){
        throw new Error(message);
    }
}
function divide(num1, num2){
    assert(typeof num1 == "number" && typeof num2 == "number",
    "divide(): Both arguments must be numbers.");
    return num1 / num2;
}
好好学习
上一篇下一篇

猜你喜欢

热点阅读