我的编程空间,编程开发者的网络收藏夹
学习永远不晚

详解JavaScript错误捕获

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

详解JavaScript错误捕获

一、基本使用与逻辑

使用


try{
    //code....
}catch(err){
    //error handling
}finally{
    //no matter what happens in the try/catch (error or no error), this code in the finally statement should run. 
}

逻辑

二、特性

try...catch 仅适用于运行时错误,解释阶段错误无法正常工作


try{
    {{{{{{{
}catch(err){
    console.error(err)
}
//引擎在‘parse-time'出错,导致无法理解代码,因此无法捕捉

try...catch 只能同步工作


try{
    setTimeout(function(){
        undefinedVariable;
    },1000)
}catch(err){
    console.error(err)
}
//setTimeout的回调函数执行时,引擎已经离开try...catch结构

finally 能让try块中的return语句失效


function test(){
  try {
    return 1;
  } catch(error) {
    return 2;
  } finally {
    return 3;
  }
}
console.log(test());
//3

三、错误对象

当程序发生error,js内部会生成一个包含error细节的对象,该对象会被作为参数传进catch

对于所有内置错误,错误对象具有两个主要属性

  • name 错误类型
  • message 文本类型的错误信息
  • stack (非标准属性)发生错误时的调用栈信息,主要用于调试

try {
  lalala; // error, variable is not defined!
} catch (err) {
  alert(err.name); // ReferenceError
  alert(err.message); // lalala is not defined
  alert(err.stack); // ReferenceError: lalala is not defined at (...call stack)

  // Can also show an error as a whole
  // The error is converted to string as "name: message"
  alert(err); // ReferenceError: lalala is not defined
}

理论上,我们可以throw任何东西作为错误对象,但最好的习惯是throw一个具有name,message的对象,以便和内置错误对象保持兼容

番外:内置的错误对象

对象 含义
ReferenceError 引用未定义变量时触发
SyntaxError 使用不合法的语法结构时触发
TypeError 值得类型非预期时触发
URIError 错误使用全局URI函数如encodeURI()、decodeURI()等时触发
RangeError 对Array构造函数使用错误的长度值,对Number.toExponential()、Number.toFixed()或Number.toPrecision()使用无效数字等
EvalError 全局函数eval()中发生的错误

四、较好的catch和throw策略

​ catch错误不单单是为了防止程序挂掉,更重要的目的是方便调试,找bug,所以对错误的处理策略,稍微可以体现出码者的优雅性

​ 俗话说的好,码者,人恒雅也,尽量遵循一个原则,catch只处理自己知道的错误

举个梨子


let json = '{ "age": 30 }'; 
try{
  let user = JSON.parse(json);  
  alert( user.name );
} catch (err) {
  console.error('JSON Error:'+err);
}

上述例子的catch策略能保证程序正常,因为catch块能catch内部所有的错误,无论是JSON.parse出错还是user.name不存在报错,都能被catch到,但两种错误都用同一种打印是不利于调试的,写成下面这样会好一点


let json = '{"age":30}'
try{
  let user =  JSON.parse(json);
  alert(user.name)
}catch(err){
   if(err instanceof SyntaxError){
       console.error('JSON Error:'+err);
   }
   else throw err;
}

每个catch块处理自己知道得,可能会出现得错误,就是说,编程人员在编程的时候,catch那些预料到的错误,而将可能自己没料到的错误抛到外面。

五、Promise的错误处理

​ 众所周知,Promise是会吞掉error的,因为promise的实现就在内部对所有error进行了捕获,且捕获到的error不是向外抛出(外指promise之外),而是沿着链找到最近的onreject回调传入,所以promise的错误处理只有两种办法

  1. 设置onreject回调
  2. 全局捕获

举个栗子


try{
    new Promise((resolve,reject)=>{
        throw new Error('promise error')
    }).catch(()=>{
        //错误在最近的onreject回调被捕获
        console.error(err);
    })
}catch(err){
    //永远不会执行,promise吞掉error
    console.error(err);
}

另外需要注意,无论是执行者函数(executor)和还是 promise 的处理程序(handler),内部发生的错误统统吞掉,相当于被隐式catch,error会自动找到最近的onreject回调传进去


try{
    new Promise((resolve,reject)=>{
        resolve();
    }).then(()=>{
        throw new Error('promise then error');
    }).catch((err){
        console.error(err);
    })
}catch(err){
    //地球毁灭之前都不会执行
    console.error(err)
}

同理,在错误找到onreject传进去之前,经过的then注册的onfulfilled回调统统失效,直到找到onreject回调,处理之后,onreject回调之后的onfulfilled回调才正常


try {
    new Promise((resolve, reject) => {
        throw new Error('promise error')
    }).then((ret) => {
        //错误没有处理,失效
        console.log('then1:' + ret)
    }).catch((err) => {
        //错误处理了,后序正常
        console.error(err);
        return 'handled'
    }).then((ret) => {
        //正常执行
        console.log('then2' + ret);
    })
} catch (err) {
    //同样的,人类毁灭之前都不会执行
    console.error(err)
}

// Error:promise error
//then2handled

那整条链一个catch都没设置会怎么样呢?

那这个error就会击穿地心,一直穿透到全局,根据宿主环境的不同触发不同的全局事件,比如说浏览器中会触发 unhandledrejection事件,node环境中也会触发unhandledRejection事件,一般会对这事件进行监听,再显示信息给编程人员或者用户

番外1:chromium / v8 / v8 / 3.29.45 的 Promise内部错误捕捉

番外2:async/await错误捕捉

六、性能损耗​

After V8 version 6 (shipped with Node 8.3 and latest Chrome), the performance of code inside try-catch is the same as that of normal code. ------ 爆栈网

(稍微测了一下,相差无几)

以上就是详解JavaScript错误捕获的详细内容,更多关于JavaScript 错误捕获的资料请关注编程网其它相关文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

详解JavaScript错误捕获

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

怎么在JavaScript中捕获错误

这篇文章将为大家详细讲解有关怎么在JavaScript中捕获错误,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。JavaScript的作用是什么1、能够嵌入动态文本于HTML页面。2、对浏览器
2023-06-14

怎么捕获await错误

本文小编为大家详细介绍“怎么捕获await错误”,内容详细,步骤清晰,细节处理妥当,希望这篇“怎么捕获await错误”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。前言Promise 是一种在 JavaScript
2023-07-04

php怎么捕获错误提示

php捕获错误提示的方法:1、通过“error_reporting(E_ALL);”输出所有错误;2、使用“try...catch”来捕获异常;3、使用set_error_handler()函数托管错误处理程序。
2017-02-21

php如何捕获错误提示

本篇内容主要讲解“php如何捕获错误提示”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“php如何捕获错误提示”吧!php捕获错误提示的方法:1、通过“error_reporting(E_ALL)
2023-06-25

golang错误捕获源码分析

这篇文章主要介绍“golang错误捕获源码分析”,在日常操作中,相信很多人在golang错误捕获源码分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”golang错误捕获源码分析”的疑惑有所帮助!接下来,请跟
2023-07-06

php curl 错误捕获的方法

php curl错误捕获的方法是通过curl_error函数来获取,curl_error函数的作用就是返回一个保护当前会话最近一次错误的字符串,其使用有语法如“string curl_error (resource $ch)”。
2016-01-18

JS前端错误监控捕获以及上报方法详解

这篇文章主要为大家介绍了前端错误监控捕获以及上报方法详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-01-08

基于Android 错误信息捕获发送至服务器的详解

程序员最头疼的事情就是bug和debug。这次debug长达20天,搞的我心力交瘁。累,因为Android兼容性,不同手机会有不同的bug出来,而且很难复现,所以就上网找了下类似保存错误log到文件再上传到服务器,现把源码也共享出来。上传至
2022-06-06

编程热搜

目录