淺談JS之Error對象


 

【前言】

   本文主要介紹下JS的Error name相關屬性.
   當 JS 引擎執行 JS代碼時,會發生各種錯誤。

①語法錯誤,通常是程序員造成的編碼錯誤或錯別字;  
②拼寫錯誤或語言中缺少的功能(可能由於瀏覽器差異);  
③來自服務器或用戶的錯誤輸出而導致的錯誤;  
④由於許多其他不可預知的因素; 

    當發生錯誤時,JS通常會停止並產生錯誤消息。技術術語是這樣描述的:JavaScript 將拋出異常(拋出錯誤)。JS實際上會創建一個Error對象,該對象帶有兩個屬性name和message。

 

【概念】

   error指程序中的非正常運行狀態,在其他編程語言中稱為“異常”或“錯誤”。解釋器會為每個錯誤情形創建並拋出一個Error對象,其中包含錯誤的描述信息。

   ECMAScript定義了六種類型的錯誤。除此之外,還可以使用Error構造方法創建自定義的Error對象,並使用throw語句拋出該對象。

ReferenceError(參考錯誤):找不到對象時
TypeError(類型錯誤):錯誤的使用了類型或對象的方法時
RangeError(范圍錯誤):使用內置對象的方法時,參數超范圍
SyntaxError(語法錯誤):語法寫錯了
EvalError(評估錯誤):錯誤的使用了Eval   
URIError(url錯誤):URI錯誤

 

【錯誤處理】

   即使程序發生錯誤,也保證不異常中斷的機制。

try{
    可能發生錯誤的代碼
}catch(err){
    只有發生錯誤時才執行的代碼
}finally{
    無論是否出錯,肯定都要執行的代碼
}

  使用要點

  • 使用try包裹的代碼,即使不出錯,效率也比不用try包裹的代碼低;
  • 在try中,盡量少的包含可能出錯的代碼;
  • 無法提前預知錯誤類型的錯誤,必須用try catch捕獲;
  • finally可以省略;

 

【主體】

(1)Error對象
    JS擁有當錯誤發生時提供錯誤信息的內置 error 對象,error 對象提供兩個有用的屬性:name 和 message。

 

(2)Error的name屬性值

   

 

(3)try 和 catch

    try 用於定義在執行時進行錯誤測試的代碼塊,catch 語句定義當 try 代碼塊發生錯誤時,所執行的代碼塊。

    catch 塊會捕捉到 try 塊中的錯誤,並執行代碼來處理它

    注意:JS語句 try 和 catch 是成對出現的,否則會出現報錯。

翻譯為未捕獲的語法錯誤:缺少捕獲或最后嘗試

   try與catch捕獲異常可以用於表單驗證,具體案例參見文章底部---→案例1

   除此之外,日常面試也常遇到此類問題,具體參見文章底部---→案例練習2

 

(4)throw

   拋出(throw)錯誤:當錯誤發生時,當事情出問題時,JavaScript 引擎通常會停止,並生成一個錯誤消息。描述這種情況的技術術語是:JavaScript 將拋出一個錯誤。

   throw 語句允許創建自定義錯誤,從技術上講能夠拋出異常(拋出錯誤),異常可以是 JavaScript 字符串、數字、布爾或對象

throw "Too big";    // 拋出文本
throw 500;          //拋出數字

   如果把 throw 與 try 和 catch 一同使用,就可以控制程序流並生成自定義錯誤消息。

 

(5)通俗理解

   ①try

   結果

   try里面的代碼錯誤的時候會報錯,但是不會拋出錯誤,他不會執行錯誤的console.log(b);而是跳過,而且這個console.log(“c”);依然執行不出來,但是,后續的代碼還是會執行。在try里面發生錯誤,不會執行錯誤后的try里面的代碼。那catch什么意思呢?

   ②catch

   結果

   接下來對上面代碼稍作修改

   結果

   當try里面的代碼沒有錯誤的時候,catch里面的代碼是不會被執行的;當try里面的代碼沒有錯誤的時候,catch就負責把錯的給捕捉到,有一堆錯誤信息error(error是對象),系統會把錯誤信息(error.message error.name)封裝到一個error對象里面,然后把error對象傳到e里面,供拋出異常使用。

   結果

   接下來再稍作修改,再在catch外面加上一條錯誤的代碼

   效果

   catch就是負責捕捉錯誤的,捕捉錯誤到程序里面,就不會拋出到控制台里面,也就不會讓程序去終止。

   如果try里面有兩個錯誤呢?

   結果

   這是因為到錯誤b他就停了,所以也就不會到c了。

 

(6)finally

   finally 語句不論之前的 try 和 catch 中是否產生異常都會執行該代碼塊。

try {
     供測試的代碼塊
}
 catch(err) {
     處理錯誤的代碼塊
} 
finally {
     無論 try / catch 結果如何都執行的代碼塊
}

 

(7)Error的name屬性值

   

    接下來依次分析下各個屬性取值

    ①RefereError

         非法引用錯誤,即引用未定義的變量或函數。

         如果一個變量未經聲明就使用的話,就會RefereError;當一個函數未經聲明就調用,也會RefereError。

         結果

    ②SyntaxError

         語法錯誤,即標點符號使用錯誤

         結果

         翻譯為:未捕獲的語法錯誤:無效或意外的令牌

    ③EvalError

         指示 eval() 函數中的錯誤。更新版本的 JavaScript 不會拋出任何 EvalError,利用SyntaxError 代替。

    ④RangeError

          一般這種錯誤也是在遞歸函數當中出現,接下來先看一個簡單的,就可以明白這個問題出現的函數:

         

         只要一運行這個函數,就會直接報上面的那個錯誤。原因:這就是因為一個函數一直遞歸調用自己,無法停止,只有在內存被塞滿(內存溢出)的時候,報錯才能夠停止。所以,有這個報錯,先檢查一下,是不是條件判斷有錯誤。

    ⑤TypeError 

         使用的值不在期望值的范圍之內,則拋出TypeError錯誤  

         

    ⑥URIError

         如果在 URI 函數中使用非法字符,則拋出URIError錯誤

         

 

(8)非標准的 Error 對象屬性

   Mozilla 火狐和 Microsoft 微軟定義了非標准的 error 對象屬性:

  • fileName (Mozilla)
  • lineNumber (Mozilla)
  • columnNumber (Mozilla)
  • stack (Mozilla)
  • description (Microsoft)
  • number (Microsoft)

   注意:它們並不會在所有瀏覽器中工作,所以要避免在公共網站使用這些非標准的Error對象屬性。

 

案例1:

<!DOCTYPE html>
<html>
<head>
  <title>es6</title>
  <style type="text/css">
    *{
      margin: 0;padding: 0;
    }
    .login_box{
      width: 600px;
      height: auto;
      margin: 100px auto;
      border: 1px solid black;
    }
    .user_info{
      width: 100%;
      height: auto;
      padding: 10px;
      box-sizing: border-box;
    }
    .user_info i{
      font-size: 14px;
      color: red;
      margin-left: 10px;
    }
    .user_info>input{
      width: 360px;
      height: 30px;
      text-align: left;
      padding-left: 10px;
    }
    .login_box>input{
      width: 30%;
      height: 30px;
      display: block;
      margin: 10px auto;
    }
  </style>
</head>
<body>
  <form class="login_box">
    <div class="user_info">
      賬號:<input type="text" name="user_name" placeholder="請輸入賬號"><i></i>
    </div>
    <div class="user_info">
      密碼:<input type="password" name="user_pwd" placeholder="請輸入密碼"><i></i>
    </div>
    <input type="submit" value="登錄"></submit>
  </form>
  <script type="text/javascript">
    var user_name = document.querySelector('input[name="user_name"]');
    var user_pwd = document.querySelector('input[name="user_pwd"]');
    var user_submit = document.querySelector('input[type="submit"]');
    var login_box = document.querySelector('.login_box');
    /* 賬號驗證 */
    user_name.addEventListener('blur',user_name_test,false);
    function user_name_test(){
      user_name.nextElementSibling.innerHTML = '';
      try {
        const name = user_name.value.replace(/ /g,'');/*g表示過濾全部空格*/
        if(name == ''){
          throw '賬號為空';
          return false;
        }else if(name.length >= 11){
          throw '最大長度為11';
          return false;
        }else{
          return true;
        }
      }catch(error){
        user_name.nextElementSibling.innerHTML = error;
      }
    }
    /* 密碼驗證 */
    user_pwd.addEventListener('blur',user_name_pwd,false);
    function user_name_pwd(){
      user_pwd.nextElementSibling.innerHTML = '';
      try {
        const pwd = user_pwd.value.replace(/ /g,'');/*g表示過濾全部空格*/
        if(pwd == ''){
          throw '密碼為空';return false;
        }else if(pwd.length < 6){
          throw '最短為6位';return false;
        }else if(pwd.length >= 10){
          throw '最長為10位';return false;
        }else{
          return true;
        }
      }catch(error){
        user_pwd.nextElementSibling.innerHTML = error;
      }
    }
    /* 表單提交 */
    user_submit.addEventListener('click',function(event){
      const user_name = user_name_test();
      const user_pwd = user_name_pwd();
      if(user_name&&user_pwd){
        login_box.submit(function(event) {
           /* Act on the event */ 
        });
      }else{
        event.preventDefault();/*禁止表單提交*/
      }
    },false);
  </script>
</body>
</html>

效果:

 

案例2:

 

案例練習2:

面試題1:
var n = 1;
function fun(){
    try{
        n++;
        return n;
    }catch(err){    
        // 沒錯誤,catch不執行
        n++;
        return n;    
    }finally{
        n++;
        return n;
    }
}
console.log(fun());// 3  return為finally的
console.log(n);// 3

面試題2:
var n = 1;
function fun(){
    try{
        n++;
        return n;
    }catch(err){
        // 沒錯誤,catch不執行
        n++;
        return n;
    }finally{
        n++;
    }
}
console.log(fun()); // 2  return為try的
console.log(n); // 3 

面試題3:
var n = 1;
function fun(){
    try{
        n++;
        n += m;  //出錯
        return n;   
    }catch(err){
        n++;
        return n;
    }finally{
        n++;
    }
}
console.log(fun());    // 3 return為catch的
console.log(n);        // 4

 

 

.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM