夜听城嚣 夜听城嚣
首页
  • 学习笔记

    • 《JavaScript高级程序设计》
    • 前端基建与架构
  • 专题分享

    • Git入门与开发
    • 前端面试题汇总
    • HTML和CSS知识点
  • 项目实践
  • 抓包工具
  • 知识管理
  • 工程部署
  • 团队规范
bug知多少
  • 少年歌行
  • 青年随笔
  • 文海泛舟
  • 此事躬行

    • 项目各工种是如何协作的
    • TBA课程学习
收藏

dwfrost

前端界的小学生
首页
  • 学习笔记

    • 《JavaScript高级程序设计》
    • 前端基建与架构
  • 专题分享

    • Git入门与开发
    • 前端面试题汇总
    • HTML和CSS知识点
  • 项目实践
  • 抓包工具
  • 知识管理
  • 工程部署
  • 团队规范
bug知多少
  • 少年歌行
  • 青年随笔
  • 文海泛舟
  • 此事躬行

    • 项目各工种是如何协作的
    • TBA课程学习
收藏
  • 第1章 什么是JavaScript
  • 第2章 HTML中的JavaScript
  • 第3章 语言基础
  • 第4章 变量、作用域与内存
  • 第5章 基本引用类型
  • 第6章 集合引用类型
  • 第7章 迭代器与生成器
  • 第8章 对象、类与面向对象编程
  • 第9章 代理与反射
  • 第10章 函数
  • 第11章 异步编程
  • 第12章 BOM
  • 第14章 DOM
  • 第15章 DOM扩展
  • 第16章 DOM2和DOM3
  • 第17章 事件
  • 第18章 动画与Canvas图形
  • 第19章 表单脚本
  • 第20章 JavaScript API
  • 第21章 错误处理与调试
    • 第23章 JSON
    • 第24章 网络请求与远程资源
    • 第25章 客户端存储
    • 第26章 模块
    • 第27章 工作者进程
    • 第28章 最佳实践
    • 《JavaScript高级程序设计》
    frost
    2022-03-31

    第21章 错误处理与调试

    ​

    # 浏览器错误报告

    可以通过浏览器控制台的 Console 查看日志和可能发生的错误。

    # 错误处理

    # try/catch

    js 使用 try/catch 语句来处理异常。

    try {
      // 可能出错的代码
      window.someFunction()
    } catch (error) {
      // 捕获错误,所有浏览器都支持 message 属性
      console.log(error.message)
    }
    
    1
    2
    3
    4
    5
    6
    7

    try 或 catch 块无法阻止 finally 块执行,包括 return 语句。

    function test() {
      try {
        return 1
      } catch (error) {
        return 2
      } finally {
        return 3
      }
    }
    
    console.log(test()) // 3
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    # 错误类型

    • Error:基类型,其他错误类型继承。
    • InternalError:在底层 JavaScript 引擎抛出异常时由浏览器抛出。
    • EvalError:在使用 eval()函数发生异常时抛出。
    • RangeError:在数值越界时抛出。
    • ReferenceError:在找不到对象时发生,比如访问不存在的变量。
    • TypeError:变量不是预期类型,或者访问不存在的方法是发生。
    • URIError:encodeURI()或 decodeURI 调用出错时发生。

    可以用 instanceof 来确定错误类型,比如:

    try {
      doSomeFunction()
    } catch (error) {
      if (error instanceof TypeError) {
        console.log('TypeError')
      }
      // ...
    }
    
    1
    2
    3
    4
    5
    6
    7
    8

    # try/catch 用法

    当 try/catch 中发生错误时,浏览器认为错误被处理了,就不会报告了(window.onerror 不能触发)。

    window.onerror = function(e) {
      console.log('error', e)
    }
    try {
      doSomeFunction()
    } catch (error) {
      console.log('try-error', error.message) // 错误已自行捕获,不会触发window.onerror
    }
    // doSomeFunction() // 会触发window.onerror
    
    1
    2
    3
    4
    5
    6
    7
    8
    9

    try/catch 语句最好用在自己无法控制的代码中,比如第三方库,因为一般不会去修改第三方库,但也许其内部会意外抛出错误。

    # 抛出错误

    通过 throw 操作符来抛出错误,抛出的值类型不限。

    try {
      // throw 1
      // throw 'hello'
      // throw [1, 2]
      // throw true
      throw new Error('something wrong')
    } catch (error) {
      console.log(error)
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9

    # 何时抛出与 try/catch

    捕获错误的目的:阻止浏览器以其默认方式响应,说白了就是吃掉错误,不让浏览器发现。

    抛出错误的目的:为错误提供有关其发生原因的说明,说白了是禁止代码继续执行,并报告错误行为。

    # onerror 事件

    浏览器相关有 2 类 error 事件可以触发:

    • window.onerror:没有被 try/catch 处理的错误,都会是 window 上触发 error 事件。尽量不要返回 false 来阻止报告错误的默认行为。
    • img.onerror:图片加载出错时触发。

    # 识别错误

    js 是弱类型语言,很多错误只有在代码运行时才会出现。常见的错误类型有 3 类:

    • 类型转换错误

      即隐式转换导致的错误,比如 ==、if、for、while等控制语句中会进行类型转换。

      解决方式是,尽可能使用===,以及 if 判断时,注意非空判断,如undefined,null,0等均会转为 false,需要注意。

    • 数据类型错误

      变量和函数参数的数据类型可能会变,但使用方不做校验的话,可能导致错误。

      解决方式是,使用前通过类型检查保证安全,如typeof,Array.isArray。

    • 通信错误

      ajax 通信过程中出现的错误,如 URL 格式不对,需要使用encodeURIComponent编码。

    # 区分错误程度

    p0 级错误:

    • 应用程序无法继续运行
    • 严重影响用户体验
    • 导致其他模块发生错误

    看下这段代码,是遍历所有模块,调用其初始化方法。

    for (let mod of mods) {
      mod.init() // 可能的重大错误
    }
    
    1
    2
    3

    问题在于,代码是同步执行的,如果其中一个模块初始化失败,抛出错误,将导致剩余的模块无法初始化。

    这属于 p0 级错误。

    解决方式如下:

    for (let mod of mods) {
      try {
        mod.init()
      } catch (e) {
        // 处理错误
      }
    }
    
    1
    2
    3
    4
    5
    6
    7

    # 错误记录

    不只是后端服务需要日志和错误记录,前端也需要。前端是直接面对用户的,如果程序异常导致用户无法继续浏览和交互,就需要相应的机制进行记录。常用的方式有:

    • ajax 请求
    • 图片上报
      • 无兼容性问题
      • 不受跨域限制

    # 调试技术

    # console

    使用 console.log 进行消息记录,可以在控制台查看。

    除了 log,还有 error,info,warn 等方法。

    浏览器控制台是 REPL(read-eval-print-loop),在控制台中执行的命令可以像页面级 JS 一样访问全局和各种 API,并且修改、对象和回调都会保留在 DOM 和运行时中。

    选择元素后,该元素会临时标记为$0,在控制台可以使用$0 引用该节点的 js 实例,可以读取属性(如$0.clientHeight)和调用成员方法(如$0.remove())。

    # debugger

    可以在源码中插入 debugger 关键字,js 运行到该行时会停在该断点。

    也支持在浏览器中手动设置断点进行调试。

    # 页面中打印

    将调试信息在 dom 中显示。

    仅开发调试阶段使用,开发完毕要清除。

    # 抛出错误

    预先检查错误可能的原因,方便使用者定位问题,可以封装一个 assert 方法来断言。

    function assert(condition, message) {
      if (!condition) {
        throw new Error(message)
      }
    }
    
    function divide(num1, num2) {
      assert(typeof num1 === 'number' && typeof num2 === 'number', 'arguments must be number')
      return num1 / num2
    }
    console.log(divide('1', 3))
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #读书笔记
    上次更新: 2022/04/19, 09:00:41
    第20章 JavaScript API
    第23章 JSON

    ← 第20章 JavaScript API 第23章 JSON→

    最近更新
    01
    提交代码时修改commit消息
    04-09
    02
    如何快速定位bug
    02-20
    03
    云端web项目开发踩坑
    08-25
    更多文章>
    Theme by Vdoing | Copyright © 2021-2025 dwfrost | 粤ICP备2021118995号
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式
    ×