浅谈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

 

 

.

转载于:https://www.cnblogs.com/jianxian/p/11278108.html

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值