高程3總結#第17章錯誤處理與調試

錯誤處理與調試

錯誤處理

try-catch語句

try{
  //可能會致使錯誤的代碼
}catch(error){
  //在錯誤發生時怎麼處理
}
  • 發生錯誤時能夠顯示瀏覽器給出的信息javascript

    try{
      window.someNonexistentFunction();
    }catch(error){
      alert(error.message);
    }
  • 在try-catch語句中是可選的,但finally子句一經使用,代碼不管如何都會執行,try語句塊中的代碼所有正常執行,finally子句會執行,若是由於出錯而執行了catch語句塊,finally子句照樣還會執行。只要代碼中包含finally子句,不管try或catch語句塊中包含什麼代碼,甚至return語句,都不會阻止finally子句的執行java

    function testFinally(){
      try{
        return 2;
      }catch(error){
        return 1;
      }finally {
        return 0;
      }
    }
  • ECMA-262定義了7種錯誤類型數組

    • Error,是基類型,其餘錯誤類型都繼承自該類型
    • EvalError,錯誤會在使用eval()函數而發生異常時被拋出瀏覽器

      new eval();//拋出EvalError
      eval=foo;//拋出EvalError
    • RangeError,在數值超出相應範圍時觸發服務器

      var items1=new Array(-20);//拋出RangeError
      var items2=new Array(Number.MAX_VALUE);//拋出RangeError
    • ReferenceError,找不到對象時,拋出這個錯誤app

      var obj=x;//在x並未聲明的狀況下拋出ReferenceError
    • SyntaxError,把語法錯誤的JavaScript傳入eval()函數時觸發ide

      eval("a++b");//拋出SyntaxError
    • TypeError,在變量中保存着意外的類型,或者訪問不存在的方式時觸發函數

      var o=new 10;//拋出TypeError
      alert("name" in true);//拋出TypeError
      Function.prototype.toString.call("name");//拋出TypeError
    • URIError,使用encodeURI()或decodeURI()而URI格式不正確時觸發

拋出錯誤

  • 與try-catch語句相配的還有一個throw操做符,用於隨時拋出自定義錯誤。拋出錯誤時,必需要給throw操做符指定一個值,這個值是什麼類型。沒有要求lua

    throw 12345;
    throw "Hello world!";
    throw true;
    throw {name:"JavaScript"};
  • 也能夠模擬出相似的瀏覽器錯誤url

    throw new SyntaxError("I don’t like your syntax.");
    throw new TypeError("What type of variable do you take me for?");
    throw new RangeError("Sorry, you just don’t have the range.");
    throw new EvalError("That doesn’t evaluate.");
    throw new URIError("Uri, is that you?");
    throw new ReferenceError("You didn’t cite your references properly.");
  • 拋出錯誤的時機

    //函數會在參數不是數組的狀況下失敗
    function process(values){
      value.sort();
      for(var i=0,len=values.length;i<len;i++){
        if(value[i]>100){
          return values[i];
        }
      }
      return -1;
    }
    • 以上代碼,不一樣瀏覽器給出不一樣錯誤信息

      • IE,屬性或方法不存在
      • Firefox,values.sort()不是函數
      • Safari,值undefined
      • Chrome,對象名沒有方法sort
      • Opera,類型不匹配
//函數重寫
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;
}
  • 重寫後的函數中,若是values參數不是數組,就會拋出一個錯誤,錯誤消息中包含了函數的名稱,以及爲何會發生錯誤的明確描述

錯誤(error)事件

  • 任何沒有經過try-catch處理的錯誤都會觸發window對象的error事件
  • 在任何Web瀏覽器中,onerror事件處理程序都不會建立event對象,但能夠接收三個參數:錯誤消息,錯誤所在的URL和行號
  • 只要發生錯誤,不管是否是瀏覽器生成的,都會觸發error事件,並執行這個事件處理程序
  • 在事件處理程序中返回false能夠阻止瀏覽器報告錯誤的默認行爲

    window.onerror=function(message,url,line){
      alert(message);
      return false;
    }

常見錯誤類型

  • 通常須要關注三種錯誤

    • 類型轉換錯誤
    • 數據類型錯誤
    • 通訊錯誤

區分致命錯誤和非致命錯誤

  • 非致命錯誤

    • 不影響用戶的主要任務
    • 隻影響頁面的一部分
    • 能夠恢復
    • 重複相同的操做能夠消除錯誤
  • 致命錯誤

    • 應用程序根本沒法繼續運行
    • 錯誤明顯影響到了用戶的主要操做
    • 會致使其餘連帶錯誤

把錯誤記錄到服務器

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

調試技術

將消息記錄到控制檯

  • 能夠經過console對象向JavaScript控制檯中寫入信息,這個對象具備下列方法

    • error(message),將錯誤信息記錄到控制檯
    • info(message),將信息性消息記錄到控制檯
    • log(message),將通常消息記錄到控制檯
    • warn(message),將警告消息記錄到控制檯
    function sum(num1, num2){
      console.log("Entering sum(), arguments are " + num1 + "," + num2);
      console.log("Before calculation");
      var result = num1 + num2;
      console.log("After calculation");
      console.log("Exiting sum()");
      return result;
    }

將消息記錄到當前頁面

  • 在頁面 中開闢一小塊區域,用以顯示信息,這個區域一般是一個元素,而該元素能夠老是出如今頁面中,但僅用於調試目的,也能夠是一個根據須要動態建立的元素

    function log(message){
      var console = document.getElementById("debuginfo");
      if (console === null){
        console = document.createElement("div");
        console.id = "debuginfo";
        console.style.background = "#dedede";
        console.style.border = "1px solid silver";
        console.style.padding = "5px";
        console.style.width = "400px";
        console.style.position = "absolute";
        console.style.right = "0px";
        console.style.top = "0px";
        document.body.appendChild(console);
      }
      console.innerHTML += "<p>" + message + "</p>";
    }

拋出錯誤

  • 可使用assert()函數代替某些函數中須要調試的if語句,以便輸出錯誤消息

    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;
    }
相關文章
相關標籤/搜索